Running luajit object file with C

From the documentation: http://luajit.org/running.html

luajit -b test.lua test.obj # Generate object file # Link test.obj with your application and load it with require("test") 

But does not explain how to do it. I guess they assume that anyone who uses Lua is also a C programmer, not the case with me! Can i get help? GCC as an example.

I would also like to do the same thing except for the byte array header C. I also cannot find the documentation.

 luajit -bt h -n test test.lua test.h 

This creates a header file, but I don't know how to start it from C. Thank you.

+4
c lua luajit
source share
2 answers

main.lua

 print("Hello from main.lua") 

app.c

 #include <stdio.h> #include "lua.h" #include "lauxlib.h" #include "lualib.h" int main(int argc, char **argv) { int status; lua_State *L = luaL_newstate(); luaL_openlibs(L); lua_getglobal(L, "require"); lua_pushliteral(L, "main"); status = lua_pcall(L, 1, 0, 0); if (status) { fprintf(stderr, "Error: %s\n", lua_tostring(L, -1)); return 1; } return 0; } 

Shell Commands:

 luajit -b main.lua main.o gcc -O2 -Wall -Wl,-E -o app app.c main.o -Ixx -Lxx -lluajit-5.1 -lm -ldl 

Replace -Ixx and -Lxx include directories and LuaJIT libraries. If you installed it in /usr/local (by default), then most GCC installations will find it without these two options.

The first command compiles the Lua source code into bytecode and inserts it into the main.o object file.

The second command compiles and binds the minimum application code C. Note that it is also linked in the embedded bytecode. -Wl,-E is required (on Linux) to export all characters from an executable file.

Now move the main.lua source file (to make sure that it really runs the embedded bytecode, not the Lua source file), and then run the application:

 mv main.lua main.lua.orig ./app # Output: Hello from main.lua 
+14
source share

Main use:

  • Generate header file using luajit
  • #include this header in the source file (s) that will reference its characters
  • Compile the source into an executable or shared binary for lua, depending on your use case.

Here is a minimal example to illustrate:

test.lua

 return { fooprint = function (s) return print("from foo: "..s) end, barprint = function (s) return print("from bar: "..s) end } 

test.h

 // luajit -b test.lua test.h #define luaJIT_BC_test_SIZE 155 static const char luaJIT_BC_test[] = { 27,76,74,1,2,44,0,1,4,0,2,0,5,52,1,0,0,37,2,1,0,16,3,0,0,36,2,3,2,64,1,2,0,15, 102,114,111,109,32,102,111,111,58,32,10,112,114,105,110,116,44,0,1,4,0,2,0,5, 52,1,0,0,37,2,1,0,16,3,0,0,36,2,3,2,64,1,2,0,15,102,114,111,109,32,98,97,114, 58,32,10,112,114,105,110,116,58,3,0,2,0,5,0,7,51,0,1,0,49,1,0,0,58,1,2,0,49,1, 3,0,58,1,4,0,48,0,0,128,72,0,2,0,13,98,97,114,112,114,105,110,116,0,13,102, 111,111,112,114,105,110,116,1,0,0,0,0 }; 

runtest.cpp

 // g++ -Wall -pedantic -g runtest.cpp -o runtest.exe -llua51 #include <stdio.h> #include <assert.h> #include "lua.hpp" #include "test.h" static const char *runtest = "test = require 'test'\n" "test.fooprint('it works!')\n" "test.barprint('it works!')\n"; int main() { lua_State *L = luaL_newstate(); luaL_openlibs(L); lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); // package, preload, luaJIT_BC_test bool err = luaL_loadbuffer(L, luaJIT_BC_test, luaJIT_BC_test_SIZE, NULL); assert(!err); // package.preload.test = luaJIT_BC_test lua_setfield(L, -2, "test"); // check that 'test' lib is now available; run the embedded test script lua_settop(L, 0); err = luaL_dostring(L, runtest); assert(!err); lua_close(L); } 

This is pretty straight forward. This example takes byte code and puts it in the package.preload table for this lua program environment. Other lua scripts can then use this by running require 'test' . The runtest built-in lua runtest does just that and outputs:

 from foo: it works! from bar: it works! 
+7
source share

All Articles