lua-users home
lua-l archive

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



On Monday, February 4, 2002, at 03:03 PM, Roberto Ierusalimschy wrote:

1) we should add a "loadlib" facility to the "core" of Lua. This is
non-ANSI C, so its inclusion should be controled by a simple define in
the makefile. This function must be in the core (like `require'), to
enable an out-of-the-box Lua instalation to use any external libraries
without recompilation.

There is a fully ANSI C implementation of loadlib that does not involve any real dynamic loading but has mostly the same semantics. Stolen from perl and python:

1) Build your extensions as normal .o/.a files, and link them into the lua executable.

2) At make time, generate a file like this:

int lua_manifest_of_libraries(S) {
   lua_register_library("lxp", "lua_lxpinit", lua_lxpinit);
   lua_register_library("lua_fltk", "lua_openfltk", lua_openfltk);
   lua_register_library("tk", "lua_opentklib", lua_opentklib);
}

and compile it into the lua binary.

3) When loadlib() runs, it first checks if the requested module is in the manifest of internal libraries. If so, it calls the function previously registered and returns successfully.

4) If the lua executable has dynamic library support, it gives the dynamic loader a chance to load an external .so or .dll and call the function. If it does so, it returns successfully.

5) Otherwise, return failure.

People doing embedding can feel free to ignore loadlib and just directly call init functions at startup like we do now.

2) because loadlib is written in non-ANSI C and is in the core of Lua,
it should be as simple as possible. That is why I advocate the use of
an auxiliar Lua file for each C library. This Lua file (that must live
in LUA_PATH, to be loaded with require) can specify the path to the C
library, select library versions based on Lua version (using _VERSION),
and whatever else that can be done in Lua. Moreover, with this Lua
file, users can always `require' a library, without worring whether the
library is written in C or in Lua (or in both).

Let me suggest again that we add lua_provide() to allow C code to assert that it has performed the functions that a require would have done. Exposing this to lua as provide("foo") would be nice as well.

Also, it might be a good idea to allow registration of bin2c'd code such that require("foo.lua") triggers evaluation of a chunk of compiled-in Lua code. This would allow people without a file system to use the require() mechanism to structure their code even on the target device.

More specifically, I think loadlib should provide:

  - loadlib(complete lib-path, init function)
  * loads the dynamic library at "complete lib-path" (something like
    /local/lib/lua/xuxu.so), and calls "init function" to initialize
the library. (If there is a pattern that specifies the "init function"
    name given the library name, let Lua do it.)

On some platforms, it may be necessary to load non-Lua libraries that Lua libraries depend on; passing nil as the init function could mean "load this shared object, but don't call anything in it." But on all SVR4 ELF systems this should not be necessary if extension .so's are built properly.

In any case, all of this knowledge about how to load the foo extension would be wrapped up in the foo.lua file, so it's not something that has to be decided in core.

3) on top of that, libraries should use some form of modules (all public
functions in a table, for instance) to control name-space polution. There
is no need that all libraries use the same scheme (altough it would be
desirable).

I agree. If auxlib had functions to support this, I would use them. It's convenient now for me to publish lxp_foo() and lxp_bar() functions; with a few additions to auxlib, it would be just as easy to publish as Lxp.foo() and Lxp.bar().

Jay