My point was that anything you do in Pharo will lower performance quite a bit, but it wont be noticable anyway unless its in a big loop or something.
Second that Pharo cannot debug such issues which is a huge deal when you work with OS stuff and OS calls. You are far better doing this outside UFFI and straight inside a C IDE because you will have an army of tools that will make your life a ton easier. Hence why I talked about performance, C coding and Pharo crashes. In my case I had to write and test the code in C to port it to UFFI because it was impossible to resolve the bugs from inside Pharo. Also crashing Pharo all the time got really annoying and I managed to corrupt a couple of images too in the process. Of course debugging C code from a C IDE is quite similar to how you work with Pharo. I also got an experience with loading libraries because I worked with Shared memory mapped files which is the technology OS uses to load DLLs. Its really low level stuff that come directly from OS kernel. It was a ton of fun. Also C is easier because obviously there is a ton of docs and all you have to do is copy paste. In case of UFFI you have to first figure out the C code and then how to convert it to UFFI so its double the effort for little gain. Its much better thing to just wrap C code and minimize the usage of UFFI. The benefits of Pharo are lost anyway as soon as you drop so low level. On Thu, Mar 16, 2017 at 3:05 PM <raffaello.giulie...@lifeware.ch> wrote: > 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 > >>> >>>>>> > >>> >>>>> > >>> >>>>> > >>> >>>> > >>> >>>> > >>> >>> > >>> >>> > >>> >> > >>> >> > >>> > > >>> > > >>> > >>> > >> > > > > > > >