这已经让我疯了很久了。我已经按照我在互联网上找到的每个教程(这里有几个例子[[1],[2],通过谷歌搜索找到了大约六个好的教程),但仍然没有明确的解释。虽然看起来它必须是相当简单的,因为缺乏文件化的解释意味着它是大多数人认为理所当然的东西。
如何将自定义模块加载到Lua中?
根据问题like this one的建议,我编写了一个构建共享库的模块,期望我可以通过require
调用加载它。但是,当我这样做时,我得到了未定义的符号错误,尽管命令nm -g mylib.so
的列表中出现了那些确切的符号。
我之前链接的那两个教程旨在创建查看*.lua
文件包装的可执行文件。也就是说,应该调用构建的*.exe
文件来运行带有自定义模块的Lua程序。
我知道这些类型的问题在这里经常被问到(如this answer所述),但我仍然感到茫然。我尝试了一些绑定包(Luabind和OOLua),但那些效果不好(例如我的earlier question - 我最终弄明白了,等等。)
然而,当我尝试将其undefined symbol: ...
加载为mod = require('mylib.so')
时,无论我遇到什么libluatest.so
错误。我该怎么做?
功能库的工作示例
对于记录,只需注册基本功能就可以了。以下代码构建为> require('libluatest')
> greet()
hello world!
时,可以使用以下命令在Lua中运行:
extern "C"
{
#include <lualib.h>
#include <lauxlib.h>
#include <lua.h>
}
#include <iostream>
static int greet(lua_State *L)
{
std::cout << "hello world!" << std::endl;
return 0;
}
static const luaL_reg funcs[] =
{
{ "greet", greet},
{ NULL, NULL }
};
extern "C" int luaopen_libluatest(lua_State* L)
{
luaL_register(L, "libluatest", funcs);
return 0;
}
libluatest.cpp
#include <string>
class MyObj
{
private:
std::string name_;
public:
MyObj();
~MyObj();
void rename(std::string name);
};
类失败示例
这就是我目前所困扰的。它似乎不想工作。
myObj.h
extern "C"
{
#include <lualib.h>
#include <lauxlib.h>
#include <lua.h>
}
#include <iostream>
#include "myObj.h"
void MyObj::rename(std::string name)
{
name_ = name;
std::cout << "New name: " << name_ << std::endl;
}
extern "C"
{
// Lua "constructor"
static int lmyobj_new(lua_State* L)
{
MyObj ** udata = (MyObj **)lua_newuserdata(L, sizeof(MyObj));
*udata = new MyObj();
luaL_getmetatable(L, "MyObj");
lua_setmetatable(L, -1);
return 1;
}
// Function to check the type of an argument
MyObj * lcheck_myobj(lua_State* L, int n)
{
return *(MyObj**)luaL_checkudata(L, n, "MyObj");
}
// Lua "destructor": Free instance for garbage collection
static int lmyobj_delete(lua_State* L)
{
MyObj * obj = lcheck_myobj(L, 1);
delete obj;
return 0;
}
static int lrename(lua_State* L)
{
MyObj * obj = lcheck_myobj(L, 1);
std::string new_name = luaL_checkstring(L, 2);
obj->rename(new_name);
return 0;
}
int luaopen_libmyObj(lua_State* L)
{
luaL_Reg funcs[] =
{
{ "new", lmyobj_new }, // Constructor
{ "__gc", lmyobj_delete }, // Destructor
{ "rename", lrename }, // Setter function
{ NULL, NULL } // Terminating flag
};
luaL_register(L, "MyObj", funcs);
return 0;
}
}
myObj.cpp
libmyObj.so
使用带有C ++ 11标准标志的简单CMake构建编译成> require('libmyObj')
。
错误
<div class="form-group has-feedback ng-scope">
<a href="#" class="btn btn- newbutton7"><strong style="text-align:center;font-size:17px;font-family: sans-serif;margin-left:-4px;">Annual Compensation</strong></a>
<a href="#" class="btn btn- newbutton8"><strong style="text-align:center;font-size:17px;font-family: sans-serif;">Monthly Payslips</strong></a>
<a href="#" class="btn btn- newbutton9"><strong style="text-align:center;font-size:17px;font-family: sans-serif;margin-left:-8px;">Investment</strong></a>
</div>
从文件'./libmyObj.so'加载模块'libmyObj'时出错: ./libmyObj.so:undefined symbol:_ZN5MyObjC1Ev stack traceback:[C]: ? [C]:在函数'require'stdin:1:在主块[C]中:?
我在Ubuntu 14.04上处理Lua 5.1。
我想知道它是否与C和C ++的混合有关......
答案 0 :(得分:2)
您似乎没有实施:
MyObj() ; ~MyObj();
并注意luaopen_ *函数,因为模块名称为myObj
,函数名称应为luaopen_libmyObj
。