lua-users home
lua-l archive

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


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.