如何注册C++;将类嵌套到Lua 我目前可以将C++类绑定到Lua中,它封装在使用 LualuRealFuff>代码>的模块中,具有适当的静态打开函数,可以执行 LualueNeMeTabase、 LualuStEngsSuffs等。效果很好
但是如果我想绑定一个嵌套类呢如何注册C++;将类嵌套到Lua 我目前可以将C++类绑定到Lua中,它封装在使用 LualuRealFuff>代码>的模块中,具有适当的静态打开函数,可以执行 LualueNeMeTabase、 LualuStEngsSuffs等。效果很好,c++,lua,C++,Lua,但是如果我想绑定一个嵌套类呢 考虑下面的C++代码: class Foo { public: Foo(){} void do_something(); class Bar { public: Bar(){} void do_something_else(); }; }; 以及Lua注册: int foo_new(lua_State* L) { new(lua_newuserdata(L, sizeof(foo))
考虑下面的C++代码:
class Foo {
public:
Foo(){}
void do_something();
class Bar {
public:
Bar(){}
void do_something_else();
};
};
以及Lua注册:
int foo_new(lua_State* L) {
new(lua_newuserdata(L, sizeof(foo)))foo();
luaL_setmetatable(L, "Foo");
return 1;
}
int foo_do_something(lua_State* L) {
Foo* foo = (Foo*)luaL_checkudata(L, 1, "Foo");
foo->do_something();
return 0;
}
int luaopen_foo(lua_State* L) {
const luaL_Reg functions[] = {
{"__index", foo_new},
{"do_something", foo_do_something},
{nullptr, nullptr}
};
if( luaL_newmetatable(L, "Foo") ) {
luaL_setfuncs(L, functions, 0);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
}
return 1;
}
...
luaL_requiref(L, "Foo", luaopen_foo, 1);
我可以在Lua中访问Foo::do_something()
,例如:
foo = Foo()
foo:do_something()
现在的问题是:我如何在Lua中注册Foo::Bar
嵌套类,以便可以这样访问它:
bar = Foo.Bar()
bar:do_something_else()
本质上,我想在Foo
元表中注册Bar
方法,而不是全局注册。我是否需要再次调用luaL\u requiref
,或者我可以在单个luaL\u requiref
中执行此操作
谢谢大家! 编辑:好的,现在这是一个完全不同的问题 是的,你可以在一个电话里完成
luaL\u requiref
函数只是用铃铛和哨子调用传递的函数,例如检查模块是否尚未加载(并更新package.loaded
表),注册相应的全局值等
我假设您不想在没有条形码的情况下将条形码
与Foo
或Foo
分开加载,因此包中的一个“Foo”
条目就足够了。同样,不需要全局条变量
所以,简单地把它作为Foo
的一个字段,就是它
另外,请确保调用过析构函数:通常,如果将lua\u newuserdata
与placement new一起使用,则需要使用\uu gc
元方法
EDIT2:修改你的luaopen\u Foo方法(注意\u调用
,而不是构造函数的\u索引
。我个人更喜欢新建
,但是如果你想将它们创建为本地f=Foo()
,那么你需要\u调用
):
如果您曾经好奇过,luaL_requiref函数(带有一些伪代码)是什么:
请注意区别:luaL_requiref
从Lua内部调用函数,这样可以确保在其执行后正确清理堆栈,例如,您可以将一些垃圾放在那里,唯一需要确保的是您的顶级值是您想要的结果,同时返回1代码>。但是,如果您直接调用该函数,您就没有这种奢侈了。因此,确保它只在堆栈顶部添加一个值。编辑:好的,现在这是一个完全不同的问题
是的,你可以在一个电话里完成
luaL\u requiref
函数只是用铃铛和哨子调用传递的函数,例如检查模块是否尚未加载(并更新package.loaded
表),注册相应的全局值等
我假设您不想在没有条形码的情况下将条形码
与Foo
或Foo
分开加载,因此包中的一个“Foo”
条目就足够了。同样,不需要全局条变量
所以,简单地把它作为Foo
的一个字段,就是它
另外,请确保调用过析构函数:通常,如果将lua\u newuserdata
与placement new一起使用,则需要使用\uu gc
元方法
EDIT2:修改你的luaopen\u Foo方法(注意\u调用
,而不是构造函数的\u索引
。我个人更喜欢新建
,但是如果你想将它们创建为本地f=Foo()
,那么你需要\u调用
):
如果您曾经好奇过,luaL_requiref函数(带有一些伪代码)是什么:
请注意区别:luaL_requiref
从Lua内部调用函数,这样可以确保在其执行后正确清理堆栈,例如,您可以将一些垃圾放在那里,唯一需要确保的是您的顶级值是您想要的结果,同时返回1代码>。但是,如果您直接调用该函数,您就没有这种奢侈了。因此,请确保它只在堆栈顶部添加一个值。您已经成为几代人的草率术语的受害者。虽然Bar
看起来有点“sub”,但它根本不是一个子类。它是一个嵌套类。我们更喜欢技术术语“基类”、“派生类”和“成员类型”,它们不容易被误解。你已经成为了几代人的草率术语的受害者。虽然Bar
看起来有点“sub”,但它根本不是一个子类。它是一个嵌套类。我们更喜欢技术术语“基类”、“派生类”和“成员类型”,它们不容易被误解。好吧,我承认我写这篇文章很快-我删除了静态
关键字。问题不在于在Lua中实例化类是否有用。它特别是关于使用luaL_requiref
注册class.Edited。你需要更详细的信息吗?我设置了全局析构函数等等,只是想把代码缩写一下。现在,我需要调用哪些函数才能将Bar
注册为您所说的字段?由于某种原因,我无法让它工作。更新。现在对你有好处吗?谢谢你澄清了我的问题所在!现在它就像一个符咒!好吧,我承认我写这篇文章很快-我删除了static
关键字。问题不在于在Lua中实例化类是否有用。它特别是关于使用luaL_requiref
注册class.Edited。你需要更详细的信息吗?我设置了全局析构函数等等,只是想把代码缩写一下。现在,我需要调用哪些函数才能将Bar
注册为您所说的字段?由于某种原因,我无法让它工作。更新。有什么好处吗
int luaopen_foo(lua_State* L)
{
static const luaL_Reg functions[] =
{
{"__call" , foo_new},
{"do_something" , foo_do_something},
{nullptr , nullptr}
};
if (luaL_newmetatable(L, "Foo"))
{
luaL_setfuncs(L, functions, 0);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
// =================
// Here, your "Foo" metatable is on top of your stack
// about to be returned as the result of your luaopen_Foo.
// Simply put another table above and set if as a Foo.Bar
if (luaopen_FooBar(L))
lua_setfield(L, -2, "Bar");
}
return 1;
}
int luaopen_FooBar(lua_State * L)
{
static const luaL_Reg functions[] =
{
{"__call" , foo_bar_new},
{"do_something_else" , foo_bar_do_something_else},
{nullptr , nullptr}
};
// luaL_newmetatable puts its result on top of the stack
// - exactly what we want for lua_setfield
if (luaL_newmetatable(L, "Foo::Bar"))
{
luaL_setfuncs(L, functions, 0);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
}
return 1; // Indicate the result is on top of the stack
}
void luaL_requiref(lua_State *L, const char *name, lua_CFunction openf, int set_global)
{
if (!try_get_already_loaded_module(modname))
{
lua_pushcfunction(L, openf); // Call the openf function
lua_pushstring(L, modname); // with modname as its argument
lua_call(L, 1, 1);
memorize_the_result_for_future(modname);
}
if (set_global)
{
lua_pushvalue(L, -1); // copy the module
lua_setglobal(L, modname); // set _G[modname] = module
}
}