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