我有以下用于测试的 C++ 代码:
#include <lua.hpp>
#include <iostream>
static int dummy(lua_State * L)
{
std::cout << "Test";
return 0;
}
int luaopen_testlib(lua_State * L)
{
lua_register(L,"dummy",dummy);
return 0;
}
我用命令编译它,它没有给我任何错误:
g++ -Wextra -O2 -c -o testlib.o main.cpp
g++ -shared -o testlib.so testlib.o
但是当我尝试在 lua 中加载它时,出现 undefined symbol 错误,如下所示:
Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio
> require"testlib"
error loading module 'testlib' from file './testlib.so':
./testlib.so: undefined symbol: _Z16lua_pushcclosureP9lua_StatePFiS0_Ei
在我看来,g++ 命令中缺少一些东西,但我整个上午都在寻找解决方案,但无法编译这个简单的示例。
编辑:
经过几次重新编译后,它返回到:
error loading module 'testlib' from file './testlib.so':
./testlib.so: undefined symbol: luaopen_testlib
这是通过添加解决的:
extern "C"
{
int luaopen_testlib(lua_State *L)
{
lua_register(L,"dummy",dummy);
return 0;
}
}
最佳答案
Lua 二进制文件被编译为 C 代码,库试图将其用作 C++。这将不起作用,因为 C++ 会进行名称修改以支持重载。由于 C 不支持重载,因此不需要名称修饰,也不会理解修饰后的名称。
解决这个问题的方法是告诉 C++ 编译器它要与之交互的 Lua 函数是纯 C 函数,它们不需要名称修改。
此外,luaopen_teSTLib
函数必须是 extern "C"
,因为它会从 C 代码中调用,不会进行任何修改。
extern "C" {
#include <lua.h>
}
#include <iostream>
static int dummy(lua_State * L)
{
(void)L;
std::cout << "Test"<<std::endl;
return 0;
}
extern "C"
int luaopen_testlib(lua_State * L)
{
lua_register(L,"dummy",dummy);
return 0;
}
我使用 Lua 5.4.2 运行测试并使用以下命令构建库:
g++ -Wall -Wextra -O2 -Isrc -c -fPIC -o testlib.o testlib.cpp
g++ -shared -o testlib.so testlib.o
注意 -Isrc
需要在我的测试设置中找到 lua.h
并且 -fPIC
需要使用 cout
在库中(但可能取决于所使用的编译器版本)。
结果是:
Lua 5.4.2 Copyright (C) 1994-2020 Lua.org, PUC-Rio
> require 'testlib'
true ./testlib.so
> dummy
function: 0x7ff07d2a0aa0
> dummy()
Test
>
在这种情况下,使用的 Lua 版本不会有任何区别。
关于c++ - 使用 gcc 为 lua 编译模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12445084/