如何将自定义模块加载到Lua中
How do you load a custom module into Lua?
这已经让我抓狂很长时间了。我遵循了我在互联网上能找到的每一个教程(以下是通过谷歌搜索找到的六个好教程中的几个例子[1],[2]),但仍然没有明确的解释。尽管这看起来一定很简单,因为缺乏书面解释意味着这是大多数人认为理所当然的事情。
如何将自定义模块加载到Lua中
根据这类问题的建议,我编写了一个模块,该模块构建了一个共享库,希望能够通过require
调用加载它。然而,当我这样做的时候,我会得到未定义的符号错误,尽管这些确切的符号出现在命令nm -g mylib.so
的列表中。
我之前链接的这两个教程旨在创建看起来像*.lua
文件包装器的可执行文件。也就是说,应该调用构建的*.exe
文件来运行带有自定义模块的Lua程序。
我知道这些类型的问题在这里被问得相当频繁(正如这个答案中所指出的),但我仍然不知所措。我尝试了一些绑定包(Luabind和OOLua),但效果并不好(例如,我之前的问题——我最终解决了)。
- 我已经用C实现了一个类++
- 我已经用thunk包装了构造函数、析构函数和函数
- 我把它建成了一个共享图书馆
然而,无论发生什么,当我尝试将其加载为mod = require('mylib.so')
时,都会出现undefined symbol: ...
错误。我该怎么做?
函数库的工作示例
记录在案,只需注册一个基本函数就可以了。当构建为libluatest.so
时,可以使用以下命令在Lua中运行以下代码:
> require('libluatest')
> greet()
hello world!
libimulatest.cpp
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;
}
类的失败示例
这就是我目前所坚持的。它似乎不起作用。
myObj.h
#include <string>
class MyObj
{
private:
std::string name_;
public:
MyObj();
~MyObj();
void rename(std::string name);
};
myObj.cpp
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;
}
}
使用在.上带有C++11标准标志的简单CMake构建编译为libmyObj.so
错误
> require('libmyObj')
从文件"加载模块"libmyObj"时出错/libmyObj.so':./libmyObj.so:未定义的符号:_ZN5MyObjC1Ev堆栈回溯:[C]:?[C] :在函数"require"中stdin:1:在主区块[C]中:?
我正在处理Ubuntu 14.04上的Lua 5.1。
我想知道这是否与C和C++的混合有关。。。
-
似乎你没有实现:
MyObj() ; ~MyObj();
-
注意luaopen_*函数,由于模块名称为
myObj
,因此函数名称应为luaopen_libmyObj
。
- std::原子加载和存储都需要吗
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 我可以从 lua 5.0.2 加载用 c++ 编写的 lua 5.3.5 dll 吗?
- 在 Lua 中加载 C++ 模块时'Attempt to index a string value'错误
- C++调用lua_dostring来加载具有"require('cjson')"的Lua Scrip引发错误:cjson.so:未定义的符号:lua_getfield
- lua加载我的c++共享库,但不加载它的依赖共享库
- 加载 Lua 文件并使用变量而不执行函数
- 可以在Lua中加载C++dll文件吗
- 如何使用LuaBridge从文件加载表?[Lua来自C++]
- Lua:加载第二个字符串后无法获取字段;
- 如何链接到 Lua 中的回调函数,以便在重新加载脚本时更新回调
- 使用require(.)或dofile(.)在Lua中加载.dll
- 无法在Lua中加载c dll模块
- 编译lua代码,存储字节码,然后加载并执行它
- lual_dofile ();不会用c++和Lua加载脚本
- 试图从C加载penlight lua模块
- 无法使用package.loadlib在Lua中动态加载库
- 如何将自定义模块加载到Lua中
- C++/SDL从lua加载字符串数组