2

lua C API を使用してテーブルを別のテーブルに移動しようとしています。たとえば、次の構造のテーブルがあります。

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

テーブル d this を a[b] の下に移動したいのですが、これは Lua で次のように実行できます。

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

私の現在のアプローチは、スタックに a[b][c][d] テーブルをロードすることなので、スタックは次のようになります。

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

次に a[b] をスタックにロードすると、次のようになります。

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

次に、d のキーをスタックに置き、d のキーとテーブル b をテーブル d の下に挿入すると、スタックは次のようになります。

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では失敗することがわかっています。説明したかっただけです。

私はテーブルの親を下ってみました (a[b] = b, lua_setglobal(L, a) を実行します) 運もありません。ここで私がどこで間違っているのか誰か知っていますか?

編集: キー/値をスタックにプッシュする方法に関する小さなコード スニペット。ここでの目標は、テーブルをあるテーブル構造から別のテーブル構造に移動することです (または、コードで呼び出しているように、親を変更します)。

http://pastebin.com/Y4540Wss

解決:

問題は、テーブルの変更を妨げるメタテーブル機能がテーブルにあることでした (本質的に、スクリプトを作成した人は、構造が重要な構成テーブルを持っていたため、この問題が発生しました)。

4

1 に答える 1

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;

スタック操作を読みやすく書く方法をまだ開発していません。

于 2013-06-20T20:53:47.287 に答える