2013-06-20 23 views
2

我正在嘗試使用lua C api將表移動到另一個表。舉例來說,我有這個結構的表格:在C api中移動lua表

a[b][c][d][e] = value 

我想移動表d這是下一個[B],我可以在Lua完成,如:

a[b][d] = a[b][c][d] 
a[b][c][d] = nil 

我現在的方法是在堆棧上加載一個並[b] [C] [d]表中,所以堆棧看起來像:

Index Value 
-1  d table 
-2  c table 
-3  b table 
-4  a table 

然後加載並[b]到堆棧,所以它看起來像:

Index Value 
-1  b table 
-2  a table 
-3  d table 
-4  c table 
-5  b table 
-6  a table 

然後把D的鍵壓入堆棧,並插入D的下表d鍵和表B,因此堆棧:

Index Value 
-1  d table 
-2  d key 
-3  b table 
-4  a table 
-5  c table 
-6  b table 
-7  a table 

然後我使用lua_settable(L,-3),做B [d] = d。

該方法適用於非表鍵,但對錶中的鍵無效。因此,將這樣的事情會失敗:

a[b][c][{}][d] = value 
a[b] = a[b][c][{}][d] 

注意,我知道在它上面將在上面,因爲關鍵將是一個新的lua表中給出的LUA失敗了,我只是想說明它。

我已經嘗試了下表父母(所以做[b] = b,lua_setglobal(L,a))沒有任何運氣。有人知道我要去哪裏嗎?

編輯: 關於如何將鍵/值推入堆棧的小代碼片段。這裏的目標是從一個表結構移動臺到另一個(或我稱之爲的代碼,重新設置父級吧)

http://pastebin.com/Y4540Wss

解決方案:

的問題是表有一定的metatable功能,防止對錶格進行更改(實質上,製作腳本的人具有配置表,其中結構是重要的,因此導致此問題。)

回答

1

如果我正確理解了您的描述,則此Lua代碼可以做到您想要的:

local ab = a[b] 
ab[d], ab[c][d] = ab[c][d], nil 

至於實施的Lua的C API中,lua2c與此機器翻譯有所幫助:

enum { lc_nformalargs = 0 }; 
const int lc_nactualargs = lua_gettop(L); 
const int lc_nextra = (lc_nactualargs - lc_nformalargs); 

/* local ab = a[b] */ 
lua_getfield(L,LUA_ENVIRONINDEX,"a"); 
lua_getfield(L,LUA_ENVIRONINDEX,"b"); 
lua_gettable(L,-2); 
lua_remove(L,-2); 
assert(lua_gettop(L) - lc_nextra == 1); 

/* ab[d], ab[c][d] = ab[c][d], nil */ 
lua_getfield(L,LUA_ENVIRONINDEX,"c"); 
lua_gettable(L,(1 + lc_nextra)); 
lua_getfield(L,LUA_ENVIRONINDEX,"d"); 
lua_gettable(L,-2); 
lua_remove(L,-2); 
lua_pushnil(L); 
lua_getfield(L,LUA_ENVIRONINDEX,"c"); 
lua_gettable(L,(1 + lc_nextra)); 
lua_insert(L,-2); 
lua_getfield(L,LUA_ENVIRONINDEX,"d"); 
lua_insert(L,-2); 
lua_settable(L,-3); 
lua_pop(L,1); 
lua_getfield(L,LUA_ENVIRONINDEX,"d"); 
lua_insert(L,-2); 
lua_settable(L,(1 + lc_nextra)); 
assert(lua_gettop(L) - lc_nextra == 1); 
return 0; 

我還沒有制定書面的堆棧操作的可讀的方式。

+1

使用'lua_getglobal'而不是'lua_getfield'。 – lhf

+0

@lhf好的,謝謝。我發現LUA_ENVIRONINDEX已從Lua 5.2中刪除。 –

+0

仍然不起作用。這可能是不同的,但其中一個表的鍵實際上是另一個表。當我沒有桌子鑰匙時,一切正常。我不確定如何在lua2c中重述這一點,因爲表可能沒有像f = {}這樣的引用。 a [f] = {}。它的做法像[{}] = {},所以我必須使用luaL_ref來獲取堆棧中的表的密鑰。 – Chrismit