Embedding LuaJIT module into C application
Asked Answered
T

1

7

In my application, I have all the Lua libraries exposed from the C backend. Now, I have a need to load a Lua module. The method for this seems to be :

lua_getglobal(L, "require");
lua_pushstring(L, libname);
lua_pcall(L, 1, 0, 0);

which will search the package.path to find <libname>.lua and load it.

Is it possible to build-in the Lua module into the C application (so that the module becomes part of the C application) ? so that I don't have to separately package the Lua module. Somehow I am not able to find any references or examples of this! :(

p.s. I am using LuaJIT-2.0.2, and the library in question is SciLua/Time (uses ffi)

Timberland answered 26/10, 2013 at 12:11 Comment(1)
possible duplicate of Running luajit object file from CSacrilege
R
6

Yes.

luajit -b Module.lua Module_bc.c

will compile a module to bytecode and output a C array initializer containing that bytecode. If you build with shared libraries enabled and export this array from the main executable, require will find it (and will not need to look for Module.lua.)

To test that it is working, set package.path = "" before requireing the module. If it still works, you know the preload is working and it is not just using the Module.lua file from the current directory.

http://luajit.org/running.html

Other things to keep in mind:

  • If the module depends on an external file (using io.open), that file still needs to be present. For example some ffi modules try to open a C header file, to pass to ffi.cdef
  • You need to keep Module_bc.c in sync with Module.lua, e.g. with a Makefile recipe, or you will see some confusing bugs!
Rudyrudyard answered 26/10, 2013 at 12:44 Comment(2)
I get the idea, and I saw the other post referred to by Mike, as well. But in my application I don't intend to use any shared libraries. So, my understanding is that, I need the luajit generated BC array, and I need to do package.preload, but I don't want the scripts to invoke require, so I also need to do lua_getglobal(L, "require");lua_pushliteral(L, "module") on the Lua state. correct?Timberland
If you don't want the script to invoke require, you will also need to store the module object in the global table. And maybe use luaL_loadbuffer instead of require. And generate a .h file instead of a .c file from luajit -b, because the .h version includes a length field but the .c version does not (and you need the length to pass to luaL_loadbuffer.)Rudyrudyard

© 2022 - 2024 — McMap. All rights reserved.