2010-07-26 42 views
8

我有一些C++中的類,我想向Lua公開。我可以通過調用Widget:New()來得到具有設置爲表WidgetMeta的metatable的userdata。 WidgetMeta在這一切的C++函數,它的__index設置爲自己,這樣我就可以做到這一點:在Lua中處理userdate像一個表

w = Widget:New() 
w:Foo() -- Foo is defined in C code 

這一切都非常簡單。

現在這裏是我無法弄清楚的部分。我希望能夠將Lua定義的變量和函數放在我的用戶數據中,就像它是一個表一樣。這顯然不能直接完成。我不能將它放在用戶數據上,因爲我希望它對每個用戶數據都是唯一的。

​​

我的攻擊目前的計劃是有元表有用戶數據和表之間的映射上有一個特殊的表,我可以存儲每個用戶數據的函數和變量。問題是我不確定最好的方法是什麼,或者是否有更好的解決方案。所以我的問題是雙重的:當我設置我的__index和__newindex元方法時,是否將它們寫入文本文件的Lua代碼中並在運行剩餘的東西之前運行它,還是直接從C中放置Lua代碼字符串在我的程序通過luaL_loadstring,或者我做到了與C接口並處理所有的堆棧操作?其次,我該如何編寫這個功能......但是一旦我決定選擇哪條路線,我會處理這個問題。

+1

jsimmons的回答是優秀的Lua的5.1和更早的版本,但在Lua 5.2,可以將表的每個用戶數據使用lua_setuservalue和準用lua_getuservalue檢索。所以5.2的答案將類似於jsimmons使用這些新的表關聯而不是函數環境的答案。 – 2013-07-25 19:23:37

回答

9

爲userdata添加一個函數環境,並通過它重定向訪問。

這是一些描述過程的舊代碼。

static int l_irc_index(lua_State* L) 
{ 
    /* object, key */ 
    /* first check the environment */ 
    lua_getfenv(L, -2); 
    lua_pushvalue(L, -2); 
    lua_rawget(L, -2); 
    if(lua_isnoneornil(L, -1) == 0) 
    { 
     return 1; 
    } 

    lua_pop(L, 2); 

    /* second check the metatable */  
    lua_getmetatable(L, -2); 
    lua_pushvalue(L, -2); 
    lua_rawget(L, -2); 

    /* nil or otherwise, we return here */ 
    return 1; 
} 

static int l_irc_newindex(lua_State* L) 
{ 
    /* object, key, value */ 

    lua_getfenv(L, -3); 
    lua_pushvalue(L, -3); 
    lua_pushvalue(L, -3); 
    lua_rawset(L, -3); 

    return 0; 
} 
+0

謝謝,這比我準備做的要乾淨得多:D – Alex 2010-07-27 03:58:00