Binary Module Tutorial |
|
VersionNotice: This page pertains to an earlier version of Lua (4.0 and 5.0beta) using a loadmodule
extension. Lua 5.1 uses package.loadlib
and require
. Lua 5.0 uses loadlib
.)
The goal of this page is to show how easy it is to create LuaBinaryModules from existing Lua extensions w/o changing the original source code of the extension in question - MartinSpernau
Goal: Compile a existing Lua-extension (that is originally statically linked to the Lua executable) as a dynamic link library ready to be loaded at runtime via the loadmodule() functionality described in LuaBinaryModules.
Special objective: do not change the original code (which most probably was written by someone else)
Discussion: A lua extension usually consist of a number of source files and header files that implement the desired functionality. The way those functions are made accessable for the Lua interpreter is via special wrapper functions, and one 'open' function that 'registers' these functions with the current Lua state. (A discussion of this can be found in the Lua reference and under BindingCodeToLua)
The loadmodule functionality (LuaBinaryModules) exploits the fact that there is basically one 'open'-function defined for each extension. As these functions can have varied names specific to each extension (e.g. lua_bitlibopen, lua_fooinizialize etc.), the loadmodule module wraps the libary opening code into one defined function luaLM_import. It also defines luaLM_version, which is needed to check for version-compatibility of the extension to the core Lua libaries.
These two functions now act as the sole external entry point of the dynamic link library that is to be complied. When called from Lua loadmodule('modname') will try to load a dll for that extension (on Windows this would be luamodname.dll). It will then check versions by calling luaLM_version and if everything is satisfying call luaLM_import, which will in turn initialize the actual registering of functions.
Porting an existing extension to act as a loadmodule enabled dll It is generally suffice to add the two needed luaLM functions to the extension, and compile it as a dynamic link library. This is usually done by writing a simple .def file that declares the two functions.
todo: add instructions on how to do this with common compilers
The author would like to describe a slightly variant method, with the benefit of requiring zero change to the original code.
ReubenThomas bitlib will be used as an example here, as it is rather small in itself and has no external dependencies. The steps described here work with most other extensions. Bitlib provides bitwise logical operations
What is needed:
#include "lua.h" extern void lua_bitlibopen (lua_State *L); /* special functions for use with loadmodule.c */ int luaLM_import( lua_State *L ) { lua_bitlibopen(L); return 0; } const char * luaLM_version( void ) { return LUA_VERSION; }
; luabitlib.def: Declares the module parameters for the DLL. LIBRARY luabitlib DESCRIPTION 'Lua bitwise operations library' EXPORTS ; Explicit exports can go here luaLM_version @1 luaLM_import @2
Now one can simply place the luabitlib.dll in a path accesible by the Lua (loadlib enabled) executale (same folder will do) and load it like this:
>loadmodule("bitlib") using bitlib >a=5 >b=2 >print(imod(a,b)) -- returns the integer remainder of a divided by b 1
The complete source and VC projectfile can be downloaded [here]
Note: Theres another convenient way of creating a library. If you already have the .lib file, you just need an empty dll project with the that lib, the proxy file and the def files, put them together and build, that's it.