2013-02-12 63 views
2

我剛剛開始使用Luabind和C++。我的目標很簡單:Lua函數在使用Luabind比較存儲的C++對象指針時崩潰

我想創建一個將C++對象指針作爲參數並將該對象存儲在Lua變量中的Lua函數。每次調用Lua函數時,都應該首先檢查傳遞給它的對象指針是否與上次調用期間存儲的對象指針是相同的對象指針。

下面是完整的代碼:

extern "C" { 
    #include "lua.h" 
    #include "lualib.h" 
} 
#include <luabind/luabind.hpp> 

class Obj { 
}; 

int main(int argc, char **argv) { 
    lua_State* cLuaState = luaL_newstate(); 
    luabind::open(cLuaState); 
    luaL_openlibs(cLuaState); 

    luabind::module(cLuaState) [ 
    luabind::class_<Obj>("Obj") 
    ]; 

    luaL_dostring(cLuaState, "\ 
    function func(v)\n\ 
     print (\"Before: x is same as v?\")\n\ 
     print (x == v)\n\ 
     x = v\n\ 
     print (\"After: x is same as v?\")\n\ 
     print (x == v)\n\ 
    end"); 

    Obj* o = new Obj(); 
    try { 
    luabind::call_function<void>(cLuaState, "func", o); 
    luabind::call_function<void>(cLuaState, "func", o); 
    } catch (std::exception &e) { 
    std::cout << "Exception thrown: " << e.what() << std::endl; 
    return 1; 
    } 
    return 0; 
} 

當我運行這個程序,我希望看到以下的輸出:

Before: x is same as v? 
false 
Setting v 
After: x is same as v? 
true 
Before: x is same as v? 
true 
Setting v 
After: x is same as v? 
true 

然而,當我運行該程序,其過程中崩潰在'x'和'v'之間進行比較時第二次調用Lua函數。這是從程序輸出結果的實際:

Before: x is same as v? 
false 
Setting v 
After: x is same as v? 
true 
Before: x is same as v? 
Exception thrown: lua runtime error 
*** Exited with return code: 1 *** 

可以看出,比較之前和「V」設置後的第一個函數調用期間的作品。但是,第一個比較在第二個函數調用期間失敗。

我一定會錯過一些非常明顯的東西,但我真的不知道它是什麼。任何人都可以看到我做錯了什麼?任何意見非常感謝!

非常感謝你, 馬丁

+0

你得到什麼實際的錯誤?您需要從Luabind異常對象中提取Lua錯誤。 – 2013-02-12 22:30:35

回答

3

我找到了解決辦法。看起來出於某種原因,Lua希望使用重載的C++ equals運算符來對兩個對象執行比較,而不是執行指針本身的比較。通過創建一個重載的相等運算符來簡單地比較兩個對象的地址並將它綁定到Lua,我就可以使它工作。

我還不確定爲什麼Lua只會在第二次函數調用時做這種比較,而不是第一次,但至少我現在有一個可行的解決方案。

完整的修改工作版本低於:

extern "C" { 
    #include "lua.h" 
    #include "lualib.h" 
} 
#include <luabind/luabind.hpp> 
#include <luabind/operator.hpp> 

class Obj { 
}; 

bool operator==(const Obj& a, const Obj& b) { 
    return &a == &b; 
} 

int main(int argc, char **argv) { 
    lua_State* cLuaState = luaL_newstate(); 
    luabind::open(cLuaState); 
    luaL_openlibs(cLuaState); 

    luabind::module(cLuaState) [ 
    luabind::class_<Obj>("Obj") 
     .def(luabind::const_self == luabind::const_self) 
    ]; 

    luaL_dostring(cLuaState, "\ 
    function func(v)\n\ 
     print (\"Before: x is same as v?\")\n\ 
     print (x == v)\n\ 
     x = v\n\ 
     print (\"After: x is same as v?\")\n\ 
     print (x == v)\n\ 
    end"); 

    Obj* o = new Obj(); 
    try { 
    luabind::call_function<void>(cLuaState, "func", o); 
    luabind::call_function<void>(cLuaState, "func", o); 
    } catch (std::exception &e) { 
    std::cout << "Exception thrown: " << e.what() << std::endl; 
    return 1; 
    } 
    return 0; 
}