Export host C functions to luajit FFI without export

  • From: Florian Wesch <fw@xxxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Wed, 21 Jan 2015 12:06:33 +0100

Hi.

Here is another way of exporting host C functions without using
-rdynamic: Create a C-side static struct that contains the function
pointers you want to make available to Lua. Then call Lua with
a lightuserdata pointing to the address of that struct. In Lua,
use ffi.cdef to define the exact same struct and then use
ffi.cast to cast the lightuserdata to a Lua type. You can then
access the struct members and call your C functions.

I wrote a C macro (tested with gcc 4.6 on Linux) that makes
this easier. Hope it is useful:

#define LUA_C_EXPORT(L, name, api_typedef, ...)   \
    do {                                            \
        static struct {                             \
            api_typedef                             \
        } exports = {                               \
            __VA_ARGS__                             \
        };                                          \
        luaL_loadstring(L,                          \
            "local ffi = require \"ffi\";"          \
            "ffi.cdef[["                            \
                "typedef struct {"                  \
                    #api_typedef                    \
                "}" name ";"                        \
            "]];"                                   \
            name " = ffi.cast(\"" name "*\", ...)"  \
        );                                          \
        lua_pushlightuserdata(L, &exports);         \
        lua_pcall(L, 1, 0, 0);                      \
    } while (0)

Using it is simple:

LUA_C_EXPORT(L, "gl",
    void (*PushMatrix)();
    void (*PopMatrix)();
,
    luaGlPushMatrix,
    luaGlPopMatrix,
);

In Lua you can then use:

gl.PushMatrix()

Notice that there is no error checking for luaL_loadstring
and lua_pcall right now. Feedback appreciated.

   Florian

Other related posts: