【问题标题】:How to use LuaJIT's ffi module when embedding?嵌入时如何使用LuaJIT的ffi模块?
【发布时间】:2011-08-20 15:44:57
【问题描述】:

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

【问题讨论】:

  • 这里有一些文档luajit.org/ext_ffi.html - hth
  • 嗯,我已经检查过了,它没有解决我的问题:(
  • 你可能会在 lua 邮件列表上发布这个更好的方法,Mike Pall 积极监控它,并且可能会发布答案
  • 如果您从邮件列表中获得答案,也可以将其发布在此处(通过 Google 搜索更有可能找到。)

标签: c lua ffi luajit


【解决方案1】:

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

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

如果我添加,则在 mingw 下运行您的示例

__declspec(dllexport) int barfunc(int foo)

在 barfunc 函数中。

在 Windows 下,luajit 是作为 dll 链接的。

【讨论】:

    【解决方案2】:

    正如 misianne 指出的,您需要导出函数,如果您使用的是 GCC,则可以使用 extern 来完成:

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

    如果您在使用 GCC 的 Linux 下遇到未定义符号的问题,请注意让链接器将所有符号添加到动态符号表中,方法是将 -rdynamic 标志传递给 GCC:

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

    【讨论】:

      【解决方案3】:

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

      • 确保使用 .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;
        }}
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-11
        • 2015-02-07
        • 2011-08-07
        • 1970-01-01
        • 2012-09-01
        • 2016-06-04
        相关资源
        最近更新 更多