SKX Project? Win32::API ?
-
@thomthom said:
@dan rathbun said:
There IS a PROPER way to do this, which is allowed and REQUIRED by the Artistic 2.0 license, under which the win32-api package is released.
I did not intend on modifying the the code in any way. Just wanted to bundle a "backup" version with my TT_Lib2 that I can load if the user haven't already installed it.
You don't have a choice.. you must modify it, in order to do what you want.
Stay tuned... I have a code example coming in the placeholder post above. (Had to get something to eat.)
-
Here is an example of using a toplevel namespace, to conditionally load a private modified version of api.so :
<span class="syntaxdefault"></span><span class="syntaxcomment">#<br /># module TNT ; Thomas Thomassen's TopLevel Namespace<br />#<br /><br /></span><span class="syntaxdefault">module TNT </span><span class="syntaxcomment"># Trondheim Norway Thomassen - Toplevel Namespace<br /><br /></span><span class="syntaxdefault"> unless defined</span><span class="syntaxkeyword">?</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">@@</span><span class="syntaxdefault">loaded_once<br /> </span><span class="syntaxkeyword">@@</span><span class="syntaxdefault">loaded_once</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">false<br /> Win32_api_so_external</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">false<br /> Win32_api_so_internal_ver</span><span class="syntaxkeyword">=</span><span class="syntaxstring">'n.n.n'<br /></span><span class="syntaxdefault"> end<br /><br /><br /> </span><span class="syntaxcomment"># Check if win32-api is loaded, or if it can be loaded<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault"> if Object</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">const_defined</span><span class="syntaxkeyword">?(;</span><span class="syntaxdefault">Win32</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment"># true, some version of Win32;;API is loaded<br /></span><span class="syntaxdefault"> Win32_api_so_external</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">true<br /> else<br /> </span><span class="syntaxcomment"># false, no version of Win32;;API is YET loaded.<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment"># 1. search for an installed version and try to load it;<br /></span><span class="syntaxdefault"> begin<br /> </span><span class="syntaxcomment"># the package should be accessable via $LOAD_PATH<br /></span><span class="syntaxdefault"> result </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> require</span><span class="syntaxkeyword">(</span><span class="syntaxstring">'win32/api'</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> rescue LoadError<br /> </span><span class="syntaxcomment"># the full package was NOT found (or loaded.)<br /></span><span class="syntaxdefault"> Win32_api_so_external</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">false<br /> rescue<br /> raise </span><span class="syntaxcomment"># any other exception<br /></span><span class="syntaxdefault"> else<br /> </span><span class="syntaxcomment"># the full package WAS found,<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment"># Let us recheck that it was LOADED with API class;<br /></span><span class="syntaxdefault"> if Object</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">const_defined</span><span class="syntaxkeyword">?(;</span><span class="syntaxdefault">Win32</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">&&</span><span class="syntaxdefault"> Win32</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">const_defined</span><span class="syntaxkeyword">?(;</span><span class="syntaxdefault">API</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment"># it WAS loaded<br /></span><span class="syntaxdefault"> Win32_api_so_external</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">true<br /> else<br /> </span><span class="syntaxcomment"># it was NOT loaded<br /></span><span class="syntaxdefault"> Win32_api_so_external</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">false<br /> end<br /> end<br /> end<br /><br /> </span><span class="syntaxcomment"># Check version of win32-api IF loaded against internal version<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault"> if Win32_api_so_external<br /> if Win32</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">API</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">VERSION </span><span class="syntaxkeyword">>=</span><span class="syntaxdefault"> Win32_api_so_internal_ver<br /> </span><span class="syntaxcomment"># just use the user's external version<br /></span><span class="syntaxdefault"> Use_external</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">true<br /> else<br /> Use_external</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">false<br /> end<br /> else<br /> Use_external</span><span class="syntaxkeyword">=</span><span class="syntaxdefault">false<br /> end<br /> <br /> if not Use_external<br /> </span><span class="syntaxcomment"># just load internal version<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault"> so_file</span><span class="syntaxkeyword">=</span><span class="syntaxstring">'api-mswin.so'</span><span class="syntaxdefault"> if RUBY_PLATFORM</span><span class="syntaxkeyword">.include?(</span><span class="syntaxstring">'mswin'</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> so_file</span><span class="syntaxkeyword">=</span><span class="syntaxstring">'api-mingw.so'</span><span class="syntaxdefault"> if RUBY_PLATFORM</span><span class="syntaxkeyword">.include?(</span><span class="syntaxstring">'mingw'</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault"> begin<br /> </span><span class="syntaxcomment"># the package should be accessable via $LOAD_PATH<br /></span><span class="syntaxdefault"> result </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> require</span><span class="syntaxkeyword">(</span><span class="syntaxstring">'tnt/win32/'</span><span class="syntaxkeyword">+</span><span class="syntaxdefault">so_file</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> rescue LoadError </span><span class="syntaxkeyword">=></span><span class="syntaxdefault"> e<br /> </span><span class="syntaxcomment"># handle load error gracefully<br /></span><span class="syntaxdefault"> if e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">message</span><span class="syntaxkeyword">.include?(</span><span class="syntaxstring">'no such file to load'</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> <br /> UI</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">messagebox</span><span class="syntaxkeyword">(</span><span class="syntaxstring">"The file '#{so_file}' could not be found!\nCheck your $LOAD_PATH array.\n"</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> <br /> end <br /> stderr</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">write</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">message</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> <br /> </span><span class="syntaxcomment">#<br /></span><span class="syntaxdefault"> rescue<br /> raise </span><span class="syntaxcomment"># any other exception<br /></span><span class="syntaxdefault"> end<br /> end<br /><br />end </span><span class="syntaxcomment"># module TNT </span><span class="syntaxdefault"></span>
beta - it could use cleanup and debugging.
So now any submodules or classes etc, can make NORMAL calls to win32-api functions, like:
Win32::API.new('GetCurrentDirectory', 'LP', 'L', 'kernel32')
Ruby begins looking in the current namespace for a module
Win32
, and backs out testing each namespace, when it gets to moduleTNT
, it will use your supplied 'nested' edition, IF it is loaded.
If it is not loaded inside your TNT module, Ruby contines searching, backing up to theTOPLEVEL_BINDING
and will find and use the standard edition if it's loaded.
Otherwise, aNameError
exception will be raised, ie, 'unknown constant Win32::API' ..same as anytime you try and use a undefined module/class. -
(bump)
Added the code example (above)
-
@thomthom said:
Well, the idea was just to avoid PITA version problems - like we have now with win32api.so where many plugins ship different versions.
The reason we have this problem.. is because really neither the Plugins nor the Tools folders, can actually be thought of or used as Common Library folders.
win32api.so and win32ole.so (as well as any other Standard Ruby library file,) do not belong in either folder.
If the user installs a full Ruby install (somewhere on their computer,) and pushes the paths to the various Ruby libraries onto the
$LOAD_PATH
, the paths to Plugins and Tools come before the Ruby lib paths.The old versions in the plugins folder will always get loaded, short-circuiting the users attempt to have the correct files loaded from the proper place.
This is also why it will be wrong to just put Berger's api.so (and other utility files,) in a win32 subfolder of Plugins (or Tools.)
If we do, we then force the user to shuffle their
$LOAD_PATH
array members around in the future, when they wish to load files from a full Ruby library folder heirarchy.It brings us back to the fact.. that Sketchup needs it's OWN full Ruby install...
.. should it be under the application folder ?
.. or under the user's appdata support folder ?
-
Note that a few changes are in the works, for win32-api, so as to make using it with either 1.8.x or 1.9.x easier.
See: [#28841] Why not create fat binary gems for all win32 utils gems?
Take note of Daniel Berger's post 3 days ago. -
Also... Dan Berger has begun pushing his updates onto the RubyGems server first.
His file list on the RubyForge site, lags behind.RubyGems for win32-api
Ruby Gems for windows-api
RubyGems for windows-pr- you can manually open the gems with 7z File Manager, and copy files out to do a manual install, if need be.
-
@dan rathbun said:
You don't have a choice.. you must modify it, in order to do what you want.
From what I understood of that license, if I made no modifications at all it could be redistributed as is.
@unknownuser said:
Permissions for Redistribution of the Standard Version
(2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package.
(3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License.
-
@unknownuser said:
(2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package ...
verbatim copies are gem packages with source (sometimes with pre-compiled binaries, rake files, manifest, gemspec.. etc. etc.
Not one file pulled out and installed in the wrong place.
You cannot ignore the other major clause that you do not interfer with a user running a standard version (which would be installed in the correct place, which is one of the Ruby Library folders.)
-
@dan rathbun said:
You cannot ignore the other major clause that you do not interfer with a user running a standard version (which would be installed in the correct place, which is one of the Ruby Library folders.)
What would interfere?
-
@thomthom said:
@dan rathbun said:
You cannot ignore the other major clause that you do not interfer with a user running a standard version (which would be installed in the correct place, which is one of the Ruby Library folders.)
What would interfere?
I explained it above in this post: http://forums.sketchucation.com/viewtopic.php?f=180&t=34124&p=300656#p300629
-
@dan rathbun said:
Step 2, compile editions for, at least
- minGW* mswin32(MSVCRT6)
Or perhaps MSVCRT 7 if you feel all XP should be up to 7 by now.
You can change the so file name after compilation, like api-mswin-60.so (to follow Dan Berger's convention.) That way you can put them all in one subfolder of YOUR plugins lib subfolder:
Ah - I missed this when I was reading your replied the first time.
Compiling it into my own namespace. That's be a safe way of doing it.
Only thing is that I'm not too up to grips with compiling. - minGW* mswin32(MSVCRT6)
-
@thomthom said:
Compiling it into my own namespace. That's be a safe way of doing it.
Only thing is that I'm not too up to grips with compiling.Me either.. Ruby is confusing.
The minGW dev kit is supposed to make compiling under that easier.
Some where I thought Dan Berger has instructions for compiling using MS VC/C++A possible Pure Ruby alternative, is to "steal" the Win32 module INTO your namespace, then remove the temporary toplevel one.
-
if
Win32
has not yet been loaded, load an edition from your TT_Lib subfolder -
from within your TT_Lib namespace, call (depending on Ruby ver)
- [v1.8.0]
Win32 = Object.const_get(:Win32).clone
* ['newer']Win32 = ::Win32.clone
-
remove the top_level Win32 module, via:
Object.instance_eval('remove_const(:Win32)')
-
run
GC.start
Note that the newset ver of win32-api is now 1.4.7 (but you must get it from the RubyGems site. The RubyForge site only has 1.4.5 available.)
-
-
What I'm stuck with is compiling it. all tutorials refer to a
make
command... -
w00t!
Got it compiled and running!
TT::Win32::API -
Now, how does the license work for distributing this binary?
-
@unknownuser said:
Distribution of Compiled Forms of the Standard Version or Modified Versions without the Source
(6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version.@unknownuser said:
Distribution of Modified Versions of the Package as Source
(4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following:(a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version.
(b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version.
(c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under
(i) the Original License or
(ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed.So, does that mean that when I've changed it to be under my own namespace I can just distribute the .so binary? Simple as that?
-
@thomthom said:
w00t!
Got it compiled and running!
TT::Win32::APIexcellent!
and ya' didn't want to use
TNT
? (AC/DC tune running thru my head.) -
@dan rathbun said:
and ya' didn't want to use
TNT
? (AC/DC tune running thru my head.)Well, I have already been using TT for a while now and all my recent plugins are under that. Trying to void creating more root namespaces.
Though I do like your explosive suggestion.Thanks for pointing out that it would be re-wrapped like that.
-
@thomthom said:
So, does that mean that when I've changed it to be under my own namespace I can just distribute the .so binary? Simple as that?
Your compliance: (if you wish, you can ask Dan Berger, what he thinks...)
(4) ... clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, ...
-
Add a README.TXT file that explains:
-
the TT edition is FUNCTIONALLY still the Standard Version, but namespace wrapped to comply with 4(b)
(4)(b)In addition, the Modified Version must bear a name that is different from the name of the Standard Version. -
the
Win32
module is loaded asTT::Win32
and theAPI
class is loaded asTT::Win32::API
; so as to comply with 4(b)* .. and that the executables are renamed as api_mingw_TT.so and api_mswin_TT.so (or whatever you named them,) in order to comply with 4(b)* you are not marketing or advertising the name "win32-api", and to most endusers, the package's use of this will be transparent.
(4)(b) ... ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version.
- Done - because you are loading it into your namespace, AND that namespace will separate your edition from the standard edition, which is loaded into the
TOPLEVEL
namespace (ie:Object
).
(5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. ...etc...
- Add to the README.TXT file the links to the RubyForge and RubyGems sites where a user could get the source, and* the instructions as I gave you (above,) on how to module wrap the Standard Version within THEIR OWN namespace.
Add Permission info to the README.TXT:
Because the MODIFIED VERSION only differs from the Standard Version by:
- being defined in the TT namespace,
which is for the protection of a normal unmodified Standard installation, * that the TT namespace is for the sole use of Thomas Thomassen,
and that the further modification of the modified version is not feasible, and has no value to any other enduser, unless that user creates a modified version for their OWN namespace from the Standard source code. * and is FUNCTIONALLY still the Standard Version, ... the TT edition is to be considered as a "portability change" under (3) of the License, and that:
"The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License."So, they have right to use under (1) of the License, viz:
(1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version.
And... include a copy of Artistic License 2.0 -
-
If the api.so is named differently it doesn't load.
4 said one only had to comply with at least on of the bullets it mentioned - so it'd be ok not to rename the binary then?
Advertisement