我有一些 lua“对象”是 C++ 对象的包装器,它们持有对 C++ 对象的本地引用并调用它。
现在我想要 C++ 中的一些函数返回那些包装器,所以我需要调用这个 lua 函数,然后在它上面设置 C++ 对象。
我遇到崩溃,我怀疑我没有正确处理 lua 堆栈。例如,如果我在退出创建包装器 + c++ 对象的函数之前询问 lua_top,我得到 5 作为结果,如果我返回 1 个对象,它不应该是 1 吗?
所以这就是我所做的,也许我做错了,也许有更好的方法来做到这一点。
c++,.h:
#define gLuaGet(L, var, type) \
if (lua_istable(L, 1)) {\
lua_getfield(L, 1, "CObj");\
lua_replace(L, 1);\
}\
type& var = *(type*)lua_touserdata(L, 1);
#define gLuaCreate(L, type) new (lua_newuserdata(L, sizeof(type))) type();
class MyObject {
public:
MyObject();
int somefunc();
};
int MyObjectCreate(lua_State *L);
int MyObjectCallSomefunc(lua_State *L);
c++,.cpp:
int MyObject::somefunc() {
std::cerr << "in c++ function" << std::endl;
return 123;
}
int MyObjectCreate(lua_State *L) {
gLuaCreate(L, MyObject);
return 1;
}
int MyObjectCallSomefunc(lua_State *L) {
gLuaGet(L, obj, MyObject);
int r = obj.somefunc();
lua_checkstack(L, 1);
lua_pushnumber(L, r);
return 1;
}
lua 包装器:
function MyObject(donotinit)
self = {}
self.CObj = nil
if (donotinit == nil) then
self.CObj = MyObjectCreate()
end
self.setCObject = function(obj)
self.CObj = obj
end
self.somefunc = function()
return MyObjectCallSomeFunc(self)
end
return self
end
现在我希望其他一些包装器返回一个在 c++ 中创建的 MyObject,所以这是从新包装器调用的 c++ 代码(为了更好地阅读,我删除了对 lua_pcall 的健全性检查):
int returnLuaMyObject(lua_State *L) {
gLuaGet(L, obj, MyOtherObject);
MyObject *myObject = obj.getMyObject(); // get c++ part
lua_getglobal(L, "MyObject"); // create lua part
lua_pushnumber(L, 1); // and tell it not to initialize the self.CObj
lua_pcall(L, 1, 1, 0);
lua_getfield(L, -1, "setCObject"); // call the setCObject function
lua_pushlightuserdata(L, myObject); // give c++ object as param
lua_pcall(L, 1, 0, 0);
// at this point lua_gettop(L); returns 5, can this be correct?
return 1;
}
好吧,如果我现在通过 lua 包装器调用这个函数几次,一切看起来都很好,但是如果我在一个 while 循环中调用它 50 次,它会在随机时间崩溃(但总是在同一 c++ 行)
我在这里做错了吗?此时 lua 堆栈顶部是否可以为 5,它只返回一个对象?