lua-users home
lua-l archive

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


Hi All!

Some time ago I wanted to clean up my C search path, which began looking as a trash bin full of unrelated DLLs side by side to lua.exe.

I tried to put different libraries in different subdirs, but then for example this idiom didn't work any longer:

local lfs = require 'lfs'

So, mixing and matching, I came up with the following solution, which worked smoothly, but since I'm quite a nitpicker :-) I'd like to have some peer-review to know if I'm doing something terribly wrong that hasn't failed yet only thanks to sheer luck. :-)

The approach is to load any C module through a Lua init file.

I'll call "root" for simplicity the root of my Lua path. Let's assume this simplified dir structure:

root--+--lfs
      |
      |
      +--lpeg
      |
      |
      +--cinvoke


in lpeg subdir I have the files:

init.lua
lpeg.dll
re.lua


-- init.lua for lpeg
local module_dir = debug.getinfo(1, "S").source:match[[^@[^\/]-$]] and "." or debug.getinfo(1, "S").source:match[[^@?(.*)[\/][^\/]-$]]

return assert(
  package.loadlib(module_dir .. [[\lpeg.dll]], "luaopen_lpeg")
)()
--------------------

That is, I use init.lua to manually load the DLL.

I know some of the limits of this approach:

- loadlib is platform dependent, but that's ok for me since I only work on Windows and that function seems to work ok there.

- if the manually loaded DLLs depends on other DLLs there may be problems on Windows, since by default dependent modules are searched in the folder of the calling executable, not in the folder of the importing DLL.

I solved this by manually pre-loading them in the init.lua using loadlib again. Of course this is doable only if they are not loadad at runtime, i.e. if I can discover the dependency using DependencyWalker.

-- init.lua for cinvoke
local module_dir = debug.getinfo(1, "S").source:match[[^@[^\/]-$]] and "." or debug.getinfo(1, "S").source:match[[^@?(.*)[\/][^\/]-$]]

-- this first loadlib is only needed to pre-load cinvoke-dll.dll
-- cinv_callback_create is just a name of any one exported function;
-- it is not called, but only used to force the loading of the DLL
-- it belongs to
assert(package.loadlib(module_dir .. [[\cinvoke-dll.dll]], "cinv_callback_create"))

return assert(
 package.loadlib(module_dir .. [[\cinvoke_lua.dll]], "luaopen_cinvoke_lua")
)()


What I wonder is whether all this stuff is really sound or I'm really missing something.

Any feedback is welcome.

Cheers.

--Lorenzo