How to use LuaJIT's ffi module when embedding?
Asked Answered
M

3

11

I'm trying to embed LuaJIT into a C application. The code is like this:

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <stdlib.h>
#include <stdio.h>

int barfunc(int foo)
{
    /* a dummy function to test with FFI */ 
    return foo + 1;
}

int
main(void)
{
    int status, result;
    lua_State *L;
    L = luaL_newstate();

    luaL_openlibs(L);

    /* Load the file containing the script we are going to run */
    status = luaL_loadfile(L, "hello.lua");
    if (status) {
        fprintf(stderr, "Couldn't load file: %s\n", lua_tostring(L, -1));
        exit(1);
    }

    /* Ask Lua to run our little script */
    result = lua_pcall(L, 0, LUA_MULTRET, 0);
    if (result) {
        fprintf(stderr, "Failed to run script: %s\n", lua_tostring(L, -1));
        exit(1);
    }

    lua_close(L);   /* Cya, Lua */

    return 0;
}

the Lua code is like this:

-- Test FFI
local ffi = require("ffi")
ffi.cdef[[
int barfunc(int foo);
]]
local barreturn = ffi.C.barfunc(253)
io.write(barreturn)
io.write('\n')

It reports error like this:

Failed to run script: hello.lua:6: cannot resolve symbol 'barfunc'.

I've searched around and found that there're really little document on the ffi module. Thanks a lot.

Mola answered 7/5, 2011 at 7:37 Comment(4)
There's some docs here luajit.org/ext_ffi.html - hthRoundworm
Well I've checked that and it didn't cover my problem :(Mola
You'll probably do way better posting this on the lua mailing list, which Mike Pall actively monitors, and will probably post an answerBismuthous
If you get an answer from the mailing list it wouldn't hurt to post it here too (where it is more likely to be found with a Google search.)Oversoul
J
9

ffi library requires luajit, so you must run lua code with luajit. From the doc: "The FFI library is tightly integrated into LuaJIT (it's not available as a separate module)".

How to embed luajit? Look here http://luajit.org/install.html under "Embedding LuaJIT"

Under mingw your example run if i add

__declspec(dllexport) int barfunc(int foo)

at the barfunc function.

Under Windows luajit is linked as a dll.

Jemina answered 7/5, 2011 at 12:33 Comment(0)
W
3

As misianne pointed out, you need to export the function, which you can do by using extern if you are using GCC:

extern "C" int barfunc(int foo)
{
    /* a dummy function to test with FFI */ 
    return foo + 1;
}

If you are experiencing problems with undefined symbols under Linux using GCC, take care to have the linker add all symbols to the dynamic symbol table, by passing the -rdynamic flag to GCC:

g++ -o application soure.cpp -rdynamic -I... -L... -llua

Wilk answered 22/4, 2012 at 19:20 Comment(0)
A
3

For those of you trying to make this work on Windows with VC++ (2012 or later), using the C++ compiler:

  • make sure you use the .cpp extension, as this will do C++ compilation
  • make the function have external C linkage so that ffi can link to it, with extern "C" { ... }
  • export the function from the executable, with __declspec(dllexport)
  • optionally specify the calling convention __cdecl, not required because should be it by default and not portable
  • wrap the Lua headers in an extern "C" { include headers }, or better just #include "lua.hpp"

    #include "lua.hpp"  
    
    extern "C" {
    __declspec(dllexport) int __cdecl barfunc(int foo) { 
     return foo + 1;
    }}
    
Ahmadahmar answered 15/11, 2013 at 0:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.