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


我正在尝试将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模块上的文档确实很少。非常感谢。


10421
2018-05-07 07:37


起源

这里有一些文档 luajit.org/ext_ffi.html  - 小时 - daven11
好吧,我已经检查过,它没有解决我的问题:( - jagttt
你可能会更好地将这个发布在lua邮件列表上,Mike Pall会主动监控,并且可能会发布一个答案 - Necrolis
如果你从邮件列表中得到答案,那么在这里发布它也不会有什么坏处(在谷歌搜索中更容易找到它。) - finnw


答案:


ffi库需要luajit,所以你必须用luajit运行lua代码。 从文档: “FFI库紧密集成到LuaJIT中(它不作为单独的模块提供)”。

如何嵌入luajit? 看这里 http://luajit.org/install.html 在“嵌入LuaJIT”下

在mingw你的例子运行,如果我添加

__declspec(dllexport) int barfunc(int foo)

在barfunc函数。

在Windows下,luajit链接为dll。


9
2018-05-07 12:33





正如misianne指出的那样,您需要导出该功能,您可以使用该功能 EXTERN 如果你使用GCC:

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

如果您在使用GCC的Linux下遇到未定义符号的问题,请注意让链接器将所有符号添加到动态符号表中,方法是 -rdynamic 加入海湾合作委员会:

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


3
2018-04-22 19:20





对于那些尝试使用VC ++(2012或更高版本)在Windows上进行此工作的人,使用C ++编译器:

  • 确保使用.cpp扩展名,因为这将进行C ++编译
  • 使该函数具有外部C链接,以便ffi可以链接到它 extern "C" { ... }
  • 从可执行文件中导出函数 __declspec(dllexport)
  • 可选地指定调用约定 __cdecl,不是必需的,因为它应该是默认的而不是便携式的
  • 将Lua标头包装在一个 extern "C" { include headers }或者更好 #include "lua.hpp" 

    #include "lua.hpp"  
    
    extern "C" {
    __declspec(dllexport) int __cdecl barfunc(int foo) { 
     return foo + 1;
    }}
    

1
2017-11-15 00:08