[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: A loadall.dll file prevents other DLLs from loading
- From: "Jérôme Vuarand" <jerome.vuarand@...>
- Date: Thu, 19 Jun 2008 15:48:34 +0200
2008/6/18 Francois Retief <fgretief@sunspace.co.za>:
> I would like to confirm an issue with Lua v5.1.3 loader_C function (in
> loadlib.c).
>
> We have two DLLs. One called loadall.dll and another called MyCompany.dll.
> Both is located in the same directory as our lua executable
> (W:\work\lua5.1.exe). The second DLL has a function called
> luaopen_MyCompany_SubSystem_UnitA that is the entry point into our module.
>
> We try to load the UnitA module into Lua, but instead get this error:
>
>> require "MyCompany.SubSystem.UnitA"
> error loading module 'MyCompany.SubSystem.UnitA' from file
> 'W:\work\loadall.dll':
> The specified procedure could not be found.
>
> It seems loadall.dll prevents Lua from finding our module. The 4th searcher
> ('all-in-one' loader) is never executed.
>
> The relevant function from the Lua 5.1.3 sources (see below) show the
> problem. In loader_C, line 409 will throw an error on the first DLL that it
> finds that does not have the correct luaopen_ function. This error stops all
> other loaders after this one. This is not what we expected to happen
> (according to the docs).
>
> 401
> 402 static int loader_C (lua_State *L) {
> 403 const char *funcname;
> 404 const char *name = luaL_checkstring(L, 1);
> 405 const char *filename = findfile(L, name, "cpath");
> 406 if (filename == NULL) return 1; /* library not found in this path */
> 407 funcname = mkfuncname(L, name);
> 408 if (ll_loadfunc(L, filename, funcname) != 0)
> 409 loaderror(L, filename); // <-- issue
> 410 return 1; /* library loaded successfully */
> 411 }
> 412
> 413
> 414 static int loader_Croot (lua_State *L) {
> 415 const char *funcname;
> 416 const char *filename;
> 417 const char *name = luaL_checkstring(L, 1);
> 418 const char *p = strchr(name, '.');
> 419 int stat;
> 420 if (p == NULL) return 0; /* is root */
> 421 lua_pushlstring(L, name, p - name);
> 422 filename = findfile(L, lua_tostring(L, -1), "cpath");
> 423 if (filename == NULL) return 1; /* root not found */
> 424 funcname = mkfuncname(L, name);
> 425 if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
> 426 if (stat != ERRFUNC) loaderror(L, filename); /* real error */
> 427 lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
> 428 name, filename);
> 429 return 1; /* function not found */
> 430 }
> 431 return 1;
> 432 }
> 433
>
> A solution to this issue would be to replace line 409 with the same code from
> lines 426 to 429 in loader_Croot.
>
> Can somebody please confirm that this is an issue in Lua 5.1.3? Or is it
> expected behaviour?
This is not a bug, but this is an issue for loadall.dll. IMHO for
regular independent binary modules, it's a useful tool that not
finding luaopen_foo in foo.dll raise an error.
An alternative solution to the one you propose would be to remove
loadall.dll from package.cpath, and use another loader for that dll
(or maybe include it in the all-in-one loader).
A more complex solution would be to raise an error when the path in
package.cpath contains a ? character, and to use fallback when it
doesn't. That way on require"foo" a package.cpath set to
"?.dll;loadall.dll" would raise an error if foo.dll doesn't contain
luaopen_foo, but would fallback to the all-in-one loader if
loadall.dll doesn't.
On the other hand, afaik, the error is only useful to detect build
problems / typos in binary modules (where the luaopen_ function is not
properly named), and your solution (ie. ignoring that error and
falling back in the list of loaders) seems perfectly acceptable to me.
Since that's the easiest solution (besides not doing anything), I
think we should go for that.