如何在嵌入时使用LuaJIT的ffi模块?

11

我正在尝试将LuaJIT嵌入到C应用程序中。 代码如下:

#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;
}

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

它报告的错误如下所示:
Failed to run script: hello.lua:6: cannot resolve symbol 'barfunc'.

我搜索了一下,发现 ffi 模块的文档非常少。非常感谢。


1
这里有一些文档 http://luajit.org/ext_ffi.html - 希望对你有帮助 - daven11
我已经检查过了,但它并没有解决我的问题 :( - jagttt
你在lua邮件列表上发布这个问题可能会收到更好的回答,因为Mike Pall经常监控该列表并可能会回复你。 - Necrolis
1
如果您从邮件列表中得到了答案,也可以在这里发布一下(这样更容易通过Google搜索找到)。 - finnw
3个回答

9

ffi库需要Luajit支持,因此您必须使用Luajit运行Lua代码。 根据文档: “FFI库与LuaJIT紧密集成(不作为单独的模块提供)”。

如何嵌入Luajit? 请参见http://luajit.org/install.html中的“嵌入LuaJIT”部分。

在mingw下,如果我添加以下内容,则可以运行您的示例:

__declspec(dllexport) int barfunc(int foo)

在barfunc函数中。

在Windows下,Luajit被链接为一个dll。


3

正如misianne指出的那样,您需要导出函数,如果您使用GCC,可以使用extern来实现:

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

如果您在Linux下使用GCC遇到未定义符号的问题,请确保通过向GCC传递-rdynamic标志,使链接器将所有符号添加到动态符号表中:

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


3

如果您正在尝试使用C++编译器在 Windows 平台(使用 VC++ 2012 或更新版本)上实现此目标,请注意以下内容:

  • 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;
    }}
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接