我試圖將一個Lua類對象推入堆棧。指向該對象的指針可以由多個函數返回。Lua userdata對象管理
換句話說:我需要推送userdata值,同時仍然保持對它們使用'==','〜='等的能力,所以如果它的相同C++對象的userdata指針必須相同。
-- this should push the object onto the stack
local firstObject = GetClassObject();
firstObject:doSomething();
firstObject將由LUA腳本存儲後來在代碼中,我需要再次做到這一點:
-- the c++ class pointer has not changed here
-- so I would like to push the same userdata pointer as in the first call...
local object = GetClassObject();
-- if I would not do this the following here would fail... :C
if object == firstObject then
...
我的Push功能應主要檢查是否已經有相同的C++類的指針某處並推動相關的用戶數據指針,如果是這樣的話(無論我如何推它,對象應該工作1:1相同)
如果不是,它應該創建一個新的userdata(將它推入堆棧)並設置它到類對象。
這裏是我的代碼:
template <typename T>
void Push(const T &tObject)
{
lua_State *L = GetLuaState();
// Here i need to check if such a C++ object (the same tObject)
// already exists!
//
// If so i want to push the associated userdata.
// Object didn't exist yet -> we need a new userdata
void *pUserData = lua_newuserdata(L, sizeof(tObject));
*reinterpret_cast<T*>(pUserData) = tObject;
}
template <typename T>
void Push(const T &tObject, const char *pszTable)
{
Push(tObject);
lua_State *L = GetLuaState();
luaL_getmetatable(L, pszTable);
lua_setmetatable(L, -2);
}
template <typename T>
T& Get(int nIndex)
{
T *pUserData = reinterpret_cast<T*>(lua_touserdata(GetLuaState(), nIndex));
if(pUserData == nullptr)
throw std::exception("Invalid userdata!");
return *pUserData;
}
template <typename T>
T& Get(int nIndex, const char *pszTable)
{
T *pUserData = reinterpret_cast<T*>(LuaToUData(nIndex, pszTable));
if(pUserData == nullptr)
throw std::exception("Invalid userdata!");
return *pUserData;
}
LuaToUData是自己的功能,我寫的不是拋出一個LUA錯誤:
void* LuaToUData(int nIndex, const char *pszTable)
{
void *pUserData = lua_touserdata(g_luaState, nIndex);
if(pUserData != nullptr)
{
if(lua_getmetatable(g_luaState, nIndex) != 0)
{
lua_getfield(g_luaState, LUA_REGISTRYINDEX, pszTable);
bool bEqual = (lua_rawequal(g_luaState, -1, -2) == 1);
lua_pop(g_luaState, 2);
if(bEqual)
return pUserData;
}
}
return nullptr;
}
我發現很難找出你在這裏想要做什麼。你只是試圖緩存一個lua userdata實例創建後? – Rook
我試圖推動userdata值,同時仍然保持對它們使用'==','〜='等的能力,所以如果它的相同C++對象的userdata指針必須是相同的。 – user1478081
Lua userdata對象在內部通過引用進行比較。從相同的基礎指針創建的兩個userdata實例應該相等比較。你是說在這種情況下'=='不起作用嗎?你有沒有重寫'__eq' metatable條目? – Rook