lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Joshua Jensen a écrit :
----- Original Message -----
From: David Burgess
Date: 1/12/2010 6:29 AM
Just so I got this problem right we have -

luadir -
  - C module dir A which contains a C module DLL
    - subordinate DLLs  which contain DLLs that A is dependent upon
  - C module dir B which contains a C module DLL
    - subordinate DLLs  which contain DLLs that B is dependent upon
  - C module dir C which contains a C module DLL
    - subordinate DLLs  which contain DLLs that C is dependent upon
I solve this problem with delay loading of DLLs. It works fantastically by adding delayimp.lib to your linked libraries and using the /DELAYLOAD:nonlua.dll to the link flags. See http://msdn.microsoft.com/en-us/library/151kt790.aspx.

At this point, there are several choices. The one I've most commonly used is to simply call LoadLibrary("full/path/to/nonlua.dll") at the first opportunity within the Lua module.

The second is to modify the PATH to include "full/path/to/". I use that one very rarely.

The final method (and apparently recommended, although I only recently learned of it) is to provide a callback function for __pfnDliNotifyHook2. See http://msdn.microsoft.com/en-us/library/z9h1h6ty.aspx.

I'm not sure if this is Visual C++ specific. What I do know is the technique works really well. In fact, LuaPlus even uses it for the Lua executable itself. A file called lua.link sits side by side with the executable. The lua.link file specifies the path to the Lua DLL. The Lua DLL and modules can exist anywhere, and only the Lua executable and lua.link file need be in the PATH.
I'm a developper of a project having similar problems with 3rd-party libraries and their path, and I solved it using the recommended using the method above.

I recommend using, as specified above, the Delay Loading of DLLs + the Notification Hook.

In your Notification Hook, hook the "case dliNotePreLoadLibrary:" to reroute LoadLibrary()... (see Microsoft's documentation). It will enable you to dynamically (at run-time) have our own C function which can known how and where (the library path) to correctly load delay-loaded libraries.

At this point, you will still encounter a problem: Delay-loaded libraries can have dependencies which are NOT delay-loaded... So the original problem arise again. Example: If you delay-load SDL_image.dll, SDL_image will probably LoadLibrary jpeg.dll at some time, and the LoadLibrary of jpeg.dll won't get through your Notification hook. To make it works, you will have to hook LoadLibraryA and LoadLibraryW into the import table of kernel32.dll for each delay-loaded library.

See http://www.codeproject.com/KB/threads/APIHooking.aspx?msg=3110895 for this purpose. (Skip DLL injection part, go straight to the source code of DLLCheck.dll)

(Yes, it's a little tricky and it will take some hours to get the whole delay-load+LoadLibrary hook working)

But in the end, it works very well :)