2016-08-16 74 views
3

我的C++程序中有對象,我將其作爲userdata傳遞給Lua,並且我重寫此用戶數據的metatable,以便對象的索引(通過__newindex和__index)導致對C的調用,C將該賦值轉換爲影響C++對象或將C++元素轉換爲Lua值(另一個用戶數據或bool,數字,字符串等基本類型)。 userdata作爲參數傳遞給從我的C++程序調用的類似事件的Lua函數。用C API替代Lua中的賦值運算符

luaL_newmetatable(L, "object"); 
lua_pushstring(L, "__index"); 
lua_pushvalue(L, -2); /* pushes the metatable */ 
lua_settable(L, -3); /* metatable.__index = metatable */ 

luaL_openlib(L, NULL, vallib_m, 0); 
luaL_openlib(L, "internal", vallib_f, 0); 

lua_pushstring(L, "__index"); 
lua_pushstring(L, "get"); 
lua_gettable(L, 2); /* get val.get */ 
lua_settable(L, 1); /* metatable.__index = val.get */ 

lua_pushstring(L, "__newindex"); 
lua_pushstring(L, "set"); 
lua_gettable(L, 2); /* get array.set */ 
lua_settable(L, 1); /* metatable.__newindex = val.set */ 

但是,這不允許我分配實際變量本身,只是變量的索引。沒有直接覆蓋賦值運算符的元事件,所以我正在尋找解決方法。

換句話說,我可以這樣做:lua_userdata_object_passed_as_arg_to_event["is_it_true"]=true ,並將其分配lua的boolean變量,以我的內部C++對象,但如果我這樣做: lua_userdata_object_passed_as_arg_to_event = new_object() 它將改變Lua的變量引用的,但它不會根據我的理解,對核心對象做任何事情。

我考慮過的一種解決方法是需要開發人員做一些破解lua_userdata_object_passed_as_arg_to_event["__self"] = new_object() 如果他們想更改對象本身,但這是不可取的。

因此,我發現了一些獨特的解決方案,通過使用全局變量覆蓋賦值運算符並重寫全局元表達式運算符,但我期待着看看是否有人能夠幫助我闡述此解決方案。見http://lua-users.org/lists/lua-l/2012-01/msg00413.htmlhttps://www.lua.org/pil/14.2.html。 特別是,我的變量是函數參數,而不是全局變量,那麼如何通過C API將其轉換爲全局變量,以便任何分配都將被自定義C函數捕獲,如果賦值發生在全局用戶數據中,將會採取行動?

順便說一下,我的userdata是一個指向對象的指針,以避免重複大對象。

回答

3

Lua和C/C++是具有不同需求的不同語言。在C/C++中,變量始終引用特定對象。你可以改變這個對象的內容,但是你永遠不能對一個不同的對象進行變量處理。如果您的電子郵件地址爲a = b;,則表示您將b的值複製到a。你永遠不能改變什麼對象a在談論。

在Lua中,變量不會永久地引用任何東西。因此,變量當前所持有的對象與該對象的值之間存在區別。

通過全局變量函數您的kludge,但local變量是不真實存在的東西。他們在Lua堆棧上的位置;你不能覆蓋Lua關於它們的默認行爲。

處理這個問題的最好方法是accept C和Lua的區別。用Lua編寫代碼的方式編寫代碼。不要試圖讓Lua代碼像C一樣工作;這種方式是愚蠢的。他們是不同的語言,你應該擁抱他們的分歧,而不是對他們不利。

如果你想讓Lua具有相當於a = b的能力,那麼你應該在你的類型中創建一個名爲assign的函數,或者可以讓你賦值給對象的值。就像要將所有表格元素從一個表格複製到另一個表格一樣,您必須編寫一個函數來完成此操作。

+0

這個問題的目標是讓Lua對用戶友好,正如我所說的,剩下的只剩下一個難題:從C中添加函數參數到當前Lua上下文中的全局變量metatable。我相信這是可能的,但只看到了各種各樣的組件,這些組件分散在不同的應用程序中,所以我試圖將它們拼湊在一起。如果這是不可能的,那麼是的,我會做一些類似於在庫中聲明assign()或者使用像「__self」這樣的自定義索引... – Leo

+0

@Leo:「*問題的目標是讓Lua用戶友好*「,但Lua *已經*」用戶友好「。它不是「完全等同於C/C++」。如果你想以某種形式的全局變量傳遞函數參數,並在函數中檢索它們,你可以。但是在Lua中,它們看起來不像函數的參數。它仍然不會改變任何本地變量不能參與的事實。 –