我正在使用SWIG將C++代碼綁定到Lua。到目前爲止它看起來不錯,但現在我需要「欺騙」並從Lua中擴展單個用戶數據,添加自定義字段和方法等。如何在Lua代碼中擴展SWIG的userdata?
我無法找到一種方法在SWIG指令中工作時完成它。我知道包裝代碼中魔術發生的地方,但我不完全理解__index和__newindex是如何工作的。此外,SWIG使用__setitem和__getitem,它被註釋爲「/ * NEW:查找__setitem()fn這是用戶提供的集合fn * /」 - 不知道這意味着什麼。最後,我的環境會自動調用腳本,在每次構建之前將SWIG指令綁定到C++包裝器,因此,如果選擇重新編譯或添加更多Lua綁定,修改源代碼非常繁瑣。
到目前爲止,我唯一的結論就是去找帶有這個功能的Lua ++。請幫助我避免很多過渡工作!
編輯:我還發現,在5.2中的「lua_setuservalue」API調用 - 它似乎很有用,但我不明白我會在所有SWIG綁定代碼中調用它。
編輯:具有
SoundObj *loadSound(const char *name)
{
return g_audio->loadSound(name); // Returns SoundObj pointer
}
這個功能是通過痛飲勢必通過在*。我痛飲定義,它的原型C函數
我創建對象:要明確的事情了。
在Lua中我寫這樣的代碼:
sound = audio.loadSound("beep.mp3")
sound.scale = 0.2
sound:play()
編輯:進步!我遵循Schollii的指示並編寫了以下Lua代碼。在這裏,「地」是使用綁定C++代碼早先獲得的用戶數據。該代碼存儲swig的__index和__newindex版本,然後重新創建這些函數,首先查詢另一個(「_other」)表。
我目前的問題是,存儲在「_other」表中的新值將在該類型的所有用戶數據對象之間共享。換句話說,如果ground.nameFoo =「ha!」,所有其他對象都有nameFoo字段存儲「ha!」。我該如何解決?
mt = getmetatable(ground)
mt._other = {}
mt.__oldindex = mt.__index
mt.__oldnewindex = mt.__newindex
mt.__index = function(tbl, key)
if mt.__oldindex(tbl, key) == nil then
if mt._other[key] ~= nil then
return mt._other[key]
end
else
return mt.__oldindex(tbl, key)
end
end
mt.__newindex = function(tbl, key, val)
if mt.__oldnewindex(tbl, key, val) == nil then
mt._other[key] = val
end
end
編輯:我實現了這個答案的解決方案:Add members dynamically to a class using Lua + SWIG
的問題是,現在我的目標類型不再是用戶數據,它是一個表。這意味着我不能再有機地將它作爲參數傳遞給以userdata作爲參數的其他綁定C++函數。任何解決方案?我必須對每個返回userdata對象的函數都這樣做。
我認爲這真的歸結爲您是否可以清楚地描述您的問題,以便有人可以提供幫助。再一次,展示你想要做的事情,不要只是描述它(代碼就像一個1000字)。你說「從Lua內部擴展一個用戶數據,添加自定義字段和方法」:好的,但是什麼?我將以添加答案爲例。注意:我沒有意識到您可以在tolua ++中做的事情無法在SWIG中完成。 – Schollii