C++ オブジェクトのラッパーである lua 'オブジェクト' がいくつかあります。それらは 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;
}
ルアラッパー:
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 になっていて、オブジェクトが 1 つしか返されないので問題ありませんか?