将方法设置为来自 C/C++/Rust 的 lua 表

Set methods to lua tables from C/C++/Rust

我想为某些 lua_State 中的某些 table 设置额外的 "methods"。

状态代码如下:

obj = {}

function obj:method1()
    print("value from second method = " .. self.method2())
end

我用do_file()方法加载。在此之后,我想将 method2() 添加到 table obj。此 method2() 必须进入堆栈 table obj (如 self)才能正常工作。

我正在尝试这样做:

state.get_global("obj");
if state.is_table(-1) {
   state.push_string("method2");
   state.push_fn(Some(method2));
   state.set_table(-3);
}

或在 C:

lua_getglobal(L, "obj");
if (lua_istable(L, -1)) {
    lua_pushstring(L, "method2");
    lua_pushcfunction(L, &lua_method2);
    lua_settable(L, -3);
}

method2() 函数写得不错,我在 "new_lib" 中使用的函数相同,它们运行良好。

当我执行所有这些操作时,我在 method2() 中检查:

if (lua_istable(L, -1)) {
    // Do some work
} else {
    print("not a table!");
}

我得到 "not a table" 而不是实际工作。

我怎么能做这样的事? Rust 中的 method2()(C/C++, whatever) 会得到 obj table (self) 作为堆栈上的第一个参数?

如果你有一个 table T 并且你调用 T:Func() 并且 T.Func 是任何函数,那么 T 将是方法调用。 因此,如果在您的代码中调用 obj:method2(),那么 obj 将是第一个参数。

请注意,您应该像 obj:method2() 这样使用 : 运算符调用该函数。如果您使用 . 运算符调用它,那么您需要将 obj table 传递给该方法,或者您 运行 进入您提到的相同的 nil 错误,因为在这种情况下没有传递任何参数. : 运算符只是 obj.method2(obj).

的语法糖

我也会尝试使用 lua_istable(L, 1),因为参数位于堆栈的底部。如果有人调用 obj:method2(2) 那么该方法将失败,因为堆栈顶部有一个数字值而不是 table。 为函数调用清除堆栈,因此传递的参数始终位于堆栈的最底部。

顺便说一句。在您的 C 代码中,您缺少函数名称的推送。