Indeed, experimenting using some combination of AddDllDirectory(),
SetDllDirectory() and LoadLibraryEx() was in my plan for next week.

Thanks



On 16/03/17 11:59, Mark Bestley wrote:
> Yes the calling process can alter where these indirect DLLs are loaded
> from and so should be able to be done in UFFI and directly from Smalltalk
> 
> The OS will load the DLL specified then it runs DllMain and doing that
> causes the OS to load any DLLs that it calls
> 
> MSDN https://msdn.microsoft.com/en-us/library/7d83bc18.aspx says
> 
> With both implicit and explicit linking, Windows first searches for
> "known DLLs", such as Kernel32.dll and User32.dll. Windows then searches
> for the DLLs in the following sequence:
> The directory where the executable module for the current process is
> located.
> The current directory.
> The Windows system directory. The GetSystemDirectory function retrieves
> the path of this directory.
> The Windows directory. The GetWindowsDirectory function retrieves the
> path of this directory.
> The directories listed in the PATH environment variable.
> 
> 
> This can be changed using the call LoadLibraryEx instead of LoadLibrary
> Flags can be set to change the directories used
> 
> https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v=vs.85).aspx
> 
> 
> 
> Also see AddDllDirectory
> https://msdn.microsoft.com/en-us/library/windows/desktop/hh310513(v=vs.85).aspx
> 
> 
> Mark
> 
> On 15/03/2017 17:22, Raffaello Giulietti wrote:
>> Hi Dimitris,
>>
>> I don't get your point about proper C coding, C performance or Pharo
>> crashes. It is not the focus of this thread.
>>
>> How dependencies between libraries are resolved at load-time is dictated
>> by the OS. If the OS offers a working mechanism to specify folders that
>> the OS uses to search for libraries at load-time, well, I think that
>> Pharo, hence the UFFI, should offer it as well and in a more fashionable
>> format.
>> UFFI is quite elegant in many respects but I wouldn't call it a
>> minimalist design (zero hand holding, if I understand you correctly).
>> But I'm happy the extra elegance is there because it makes life more
>> comfortable.
>>
>> Again, I still have to experiment with SetDllDirectory() in the case of
>> Windows, so I'm not in a position to say something authoritative yet.
>>
>>
>>
>>
>>
>>
>>
>> On 2017-03-15 17:41, Dimitris Chloupis wrote:
>>> Please note the moment you use a FFI of any language you step to a C
>>> territory. VMs tend not to touch the code because the code is already
>>> in machine code format.
>>>
>>> There is zero reason for UFFI to worry about the dependencies of a
>>> library loaded, this must happen at the library level that UFFI does
>>> not focus on.
>>>
>>> What you describe here is standard practice because the vast majority
>>> of libraries depend on other libraries. In the end UFFI or any FFI in
>>> any language is not there to replace proper C coding but rather to
>>> allow you to utilize C libraries. You cannot hope to achieve
>>> performance comparable to C if you try to use a language that is not C
>>> to do standard things like dependency management.
>>>
>>> If the library fail to load it wont be because of UFFI it will be
>>> because the library is buggy at handling its dependencies. That means
>>> that the library will be buggy even if you use it from C directly.
>>>
>>> Even you do not know what you doing at C level, you going to crash
>>> Pharo countless times anyway and the least of your worries will be
>>> handling dependencies which far more obvious than some other nasty C
>>> bugs.
>>>
>>> I think its a great idea that UFFI does zero hand holding. This way it
>>> gives the clear message that if you do not understand C then you
>>> should not be using the UFFI in the first place.
>>>
>>> On Wed, Mar 15, 2017 at 4:51 PM Esteban Lorenzano
>>> <esteba...@gmail.com
>>> <mailto:esteba...@gmail.com>> wrote:
>>>
>>>
>>>     > On 15 Mar 2017, at 15:44, Raffaello Giulietti
>>>     <raffaello.giulie...@lifeware.ch
>>>     <mailto:raffaello.giulie...@lifeware.ch>>
>>>     wrote:
>>>     >
>>>     > On 2017-03-15 15:20, Esteban Lorenzano wrote:
>>>     >>
>>>     >>> On 15 Mar 2017, at 15:08, Raffaello Giulietti
>>>     <raffaello.giulie...@lifeware.ch
>>>     <mailto:raffaello.giulie...@lifeware.ch>>
>>>     wrote:
>>>     >>>
>>>     >>> Hi Esteban,
>>>     >>>
>>>     >>> I understand this is the current status of the UFFI, so I can
>>>     certainly use the workarounds discussed below.
>>>     >>>
>>>     >>> But I hope UFFI will soon offer a more "declarative" way to
>>>     specify the search folders, kind of LD_LIBRARY_PATH mechanism but
>>>     in the UFFI.
>>>     >>
>>>     >> that will NOT solve the problem of dependencies of libraries
>>>     indirectly references.
>>>     >> There is no way to do that (indirect reference solving) on an
>>>     executing program that I know.
>>>     >> So is not “current status of UFFI”: it will never provide that.
>>>     >>
>>>     >
>>>     > Do you mean that SetDllDirectory() has no influence when invoked
>>>     between Pharo's start and the LoadLibrary() call done by the UFFI?
>>>
>>>     I really have no idea. You can try to add it to your app.
>>>
>>>     Esteban
>>>
>>>     >
>>>     >
>>>     >
>>>     >
>>>     >> All that, unless someone come and says: "look, Esteban is like
>>>     this”.
>>>     >>
>>>     >> I spent last three weeks (not full time of course) trying to do
>>>     exactly that for our current linux vm, to force libgit2 to use the
>>>     version of libssh2 we want (and not the version on system)… and I
>>>     failed. I solved some cases, but not all. So at the end I opted to
>>>     change zeroconf to define LD_LIBRARY_PATH before calling pharo.
>>>     Only way I found I can force the lookup paths.
>>>     >>
>>>     >> cheers,
>>>     >> Esteban
>>>     >>
>>>     >>>
>>>     >>>
>>>     >>>
>>>     >>> Greetings
>>>     >>> Raffaello
>>>     >>>
>>>     >>>
>>>     >>>
>>>     >>>
>>>     >>> On 2017-03-15 14:52, Esteban Lorenzano wrote:
>>>     >>>> Hi,
>>>     >>>>
>>>     >>>> UFFI cannot do what you want.
>>>     >>>> If I understand well, you have:
>>>     >>>>
>>>     >>>> Pharo -> libA.dll -> libB.dll
>>>     >>>>
>>>     >>>> Pharo does a LoadLibrary(libA.dll), but has no control on how
>>>     libA calls libB… and is not possible for us to influence it more
>>>     than the predefined platform ways.
>>>     >>>>
>>>     >>>> One posible workaround (just possible, no idea if it will
>>>     work) is to perform a load of libB before is required by libB.
>>>     Then hopefully the loader will understand is same library and will
>>>     answer same handler (but not sure, because if it discriminates by
>>>     path… then you’re in the same position). Anyway, if you want to
>>>     try it, it would be something like this:
>>>     >>>>
>>>     >>>> DynamicLoader loadLibrary: 'path/to/libB.dll’.
>>>     >>>> DynamicLoader loadLibrary: 'path/to/libA.dll’.
>>>     >>>>
>>>     >>>> then you can try to execute functions of libA…
>>>     >>>>
>>>     >>>> cheers,
>>>     >>>> Esteban
>>>     >>>>
>>>     >>>>
>>>     >>>>> On 15 Mar 2017, at 14:32, Raffaello Giulietti
>>>     <raffaello.giulie...@lifeware.ch
>>>     <mailto:raffaello.giulie...@lifeware.ch>>
>>>     wrote:
>>>     >>>>>
>>>     >>>>> On 2017-03-15 13:51, Ben Coman wrote:
>>>     >>>>>>
>>>     >>>>>>
>>>     >>>>>> On Wed, Mar 15, 2017 at 4:42 PM, Raffaello Giulietti
>>>     >>>>>>
>>>     <raffaello.giulie...@lifeware.ch
>>>     <mailto:raffaello.giulie...@lifeware.ch>
>>>     >>>>>>
>>>     <mailto:raffaello.giulie...@lifeware.ch
>>> <mailto:raffaello.giulie...@lifeware.ch>>>
>>>     wrote:
>>>     >>>>>>
>>>     >>>>>>  Hi Ben,
>>>     >>>>>>
>>>     >>>>>>  my understanding is that SetDllDirectory only affects the
>>>     search
>>>     >>>>>>  path of libraries that are loaded at *run-time* with
>>>     LoadLibrary.
>>>     >>>>>>
>>>     >>>>>>  What I'm asking for is a mechanism that works at
>>>     *load-time*, when a
>>>     >>>>>>  library I'm accessing directly depends on another one
>>>     which I'm not
>>>     >>>>>>  targeting directly.
>>>     >>>>>>
>>>     >>>>>>
>>>     >>>>>> I don't quite follow.  I'm not intimate with Windows
>>>     dynamic loading, so
>>>     >>>>>> these questions are an opportunity for me to learn...
>>>     >>>>>>
>>>     >>>>>> You can't mean when Pharo loads, because it wouldn't know
>>>     of OTHER.DLL ?
>>>     >>>>>>
>>>     >>>>>> Do you mean that LoadLibrary is not called explicitly by
>>>     YOUR.DLL before
>>>     >>>>>> its uses the function from OTHER.DLL?
>>>     >>>>>>
>>>     >>>>>
>>>     >>>>> During the build of YOUR.DLL, you can specify that it should
>>>     depend on OTHER.LIB (kind of binary which lists function headers
>>>     and static data declarations for OTHER.DLL). Linking resolution is
>>>     then done at load-time of YOUR.DLL, not by invoking
>>>     LoadLibrary("OTHER.DLL").
>>>     >>>>>
>>>     >>>>> When YOUR.DLL is loaded by UFFI at run-time (here by means
>>>     of LoadLibrary(), I guess), Windows (not the UFFI) also attempts
>>>     to load OTHER.DLL because of the linking information gathered
>>>     during the build. Notice that the linking information does *not*
>>>     include a specific path for OTHER.DLL.
>>>     >>>>>
>>>     >>>>> (You don't have to mention standard *.LIBs like Kernel32.lib
>>>     because they are included by default. But of course, Windows knows
>>>     where to find the corresponding .dll.)
>>>     >>>>>
>>>     >>>>> OTHER.DLL is searched using the strategy described in the
>>>     MSDN page you mention. My expectation is/was that UFFI has/had an
>>>     API for specifying the search paths where to find OTHER.DLL in a
>>>     platform-independent way. In other words, I would expect the UFFI
>>>     to do the call of SetDllDirectory() or whatever is needed on
>>>     Windows for me or to use other mechanisms on other platforms.
>>>     >>>>>
>>>     >>>>>
>>>     >>>>>
>>>     >>>>>> Do you mean you link OTHER.DLL to YOUR.DLL at compile time?
>>>     >>>>>> But still, YOUR.DLL it not loaded until called via Pharo
>>>     FFI, so neither
>>>     >>>>>> is OTHER.DLL,
>>>     >>>>>> and Dynamic-Link Library Search Order [1] says... "If a DLL
>>>     with the
>>>     >>>>>> same module name
>>>     >>>>>> is already loaded in memory, the system uses the loaded
>>>     DLL, no matter
>>>     >>>>>> which directory it is in.
>>>     >>>>>> The system does not search for the DLL."
>>>     >>>>>>
>>>     >>>>>> So maybe before calling any of YOUR.DLL,
>>>     >>>>>> do a SetDllDirectory followed by a LoadLibrary(OTHER.DLL)
>>>     >>>>>> and later when you call into YOUR.DLL,
>>>     >>>>>> OTHER.DLL is already loaded.
>>>     >>>>>>
>>>     >>>>>
>>>     >>>>> Yes, this might work but is rather contrived.
>>>     >>>>>
>>>     >>>>>
>>>     >>>>>
>>>     >>>>>> Otherwise it would seems(?) your options are either Manifests
>>>     >>>>>> or Dynamic-Link Library Redirection, both done outside of
>>>     Pharo.
>>>     >>>>>>
>>>     >>>>>
>>>     >>>>> What if neither YOUR.DLL nor OTHER.DLL are under my control?
>>>     The only thing I know is where the .dll and the corresponding .lib
>>>     + .h are.
>>>     >>>>>
>>>     >>>>>
>>>     >>>>>
>>>     >>>>> Thanks for your interest
>>>     >>>>> Raffaello
>>>     >>>>>
>>>     >>>>>
>>>     >>>>>
>>>     >>>>>
>>>     >>>>>>  But I'll try whether SetDllDirectory also affects
>>>     load-time searches.
>>>     >>>>>>
>>>     >>>>>>  Anyway, I hope future versions of the UFFI to offer
>>>     setting the
>>>     >>>>>>  search paths more easily.
>>>     >>>>>>
>>>     >>>>>>
>>>     >>>>>>
>>>     >>>>>>  Greetings
>>>     >>>>>>  Raffaello
>>>     >>>>>>
>>>     >>>>>
>>>     >>>>>
>>>     >>>>
>>>     >>>>
>>>     >>>
>>>     >>>
>>>     >>
>>>     >>
>>>     >
>>>     >
>>>
>>>
>>
> 
> 


Reply via email to