【问题标题】:Can't load shared library (compiled with C++ and Luabind) package into Lua无法将共享库(使用 C++ 和 Luabind 编译)包加载到 Lua
【发布时间】:2016-12-07 07:53:45
【问题描述】:

我已经从 Luabind 文档中为 "basic usage" example 编译了共享库。但是,我无法从 Lua 调用它。

lbtest.cpp

extern "C"
{
    #include "lua.h"
}
#include <iostream>
#include <luabind/luabind.hpp>

void greet()
{
    std::cout << "hello world!\n";
}

extern "C" int init(lua_State* L)
{
    using namespace luabind;

    open(L);

    module(L)
    [
        def("greet", &greet)
    ];

    return 0;
}

这将编译为 liblbtest.so。但是,当我运行命令时(如this answer 中所述)

> lua
> package.loadlib('liblbtest.so', 'init')()
> greet()

我收到此错误:

stdin:1: 尝试调用全局“greet”(一个 nil 值)堆栈回溯: stdin:1: 在主块 [C]: ?

我已经尝试了一些测试:

> fn, err = package.loadlib('liblbtest.so', 'init')
> print(fn)
nil

> fn, err = package.loadlib('liblbtest.so', 'init')()
stdin:1: attempt to call a nil value
stack traceback:
    stdin:1: in main chunk
    [C]: ?

> fn, err = package.loadlib('liblbtest.so', '_init')()
> print(fn)
nil

> fn, err = package.loadlib('liblbtest.so', '_init')
> print(fn)
function 0x1332e90

所有这些loadlib 调用在调用greet() 时都会导致相同的错误(如前所述的 nil 值)。有趣的是,最后一个似乎至少返回了一个函数。

我正在运行带有 Lua 5.1.5 的 Ubuntu 14.04。

如何让它工作?


更新

当我删除“.so”后缀并开始使用require 语法(根据this Lua mailing list conversation)时,我确实遇到了另一个错误

> require('liblbtest')
error loading module 'liblbtest' from file './liblbtest.so':
    ./liblbtest.so: undefined symbol: luaopen_liblbtest
stack traceback:
    [C]: at 0x0047aff0
    [C]: in function 'require'
    stdin:1: in main chunk
    [C]: at 0x00406670

但是,使用nm -gC liblbtest.so 命令我没有看到导出的符号。我该如何做到这一点?

【问题讨论】:

  • 使用ldd -r &lt;yourobject&gt; 和(也许)ldd -d &lt;yourobject&gt; 您是否看到所有内容都按预期导出?
  • @M4rc:我是。或者至少我是这么认为的。依赖项似乎都指向正确的目录。我倾向于认为它与我的共享对象关系不大,而与我如何将它加载到 Lua 脚本中有关。但我愿意犯错误
  • 如果您运行readelf -Ws,您是否在其中看到了您的init 函数和greet 函数? AFAIK _init() 可能保留给 C++ 的入口点。
  • @M4rc 我确实看到了问候 _ZL5greetv 。我想我将 init 视为_ZStL8__ioint
  • 我不能完全不关心它是什么——你可以在你的平台上运行c++filt _ZStL8__ioint 来解开它。我相信这是 stl 初始化的入口点,在您的情况下可能是 cout

标签: c++ lua luabind


【解决方案1】:

您的 C DLL 不遵循 lua C api DLL 的格式。请尝试: __declspec(dllexport) int luaopen_liblbtest(lua_State* L) { lua_register(L, "init", init); 返回 1; }

【讨论】:

    猜你喜欢
    • 2012-07-21
    • 2014-07-16
    • 1970-01-01
    • 2018-04-07
    • 2020-12-10
    • 2015-08-06
    • 2012-10-14
    • 1970-01-01
    • 2021-09-24
    相关资源
    最近更新 更多