0

Lua スクリプトから呼び出される C 関数でluaL_ref、関数への参照を格納するために使用しています。ただし、返された整数インデックスを使用して、同じ状態から派生していない別のスレッドからその関数をフェッチしようとすると、返されるのはnil. これを示す最も簡単な例を次に示します。

// Assumes a valid lua_State pL, with a function on top of the stack
int nFunctionRef = luaL_ref(pL, LUA_REGISTRYINDEX);

// Create a new state
lua_State* pL2 = luaL_newstate();
lua_rawgeti(pL2, LUA_REGISTRYINDEX, nFunctionRef);
const char* szType = luaL_typename(pL2, -1);

szTypeその後、値「nil」が含まれていることがわかりました。

私の理解では、レジストリはすべての C コードでグローバルに共有されていたので、なぜこれが機能しないのか説明できますか?

レジストリがそのようにグローバルに共有されていない場合、別のスクリプトから必要なように値にアクセスするにはどうすればよいですか?

4

3 に答える 3

7

レジストリは Lua 状態の通常のテーブルにすぎないため、関連のない 2 つの Lua 状態が同じレジストリにアクセスすることはできません。

Kknd が言うように、独自のメカニズムを提供する必要があります。一般的なトリックは、コードを実行しない余分な状態を作成することです。これはストレージとしてのみ使用されます。あなたの場合、C コードからその余分な状態のレジストリを使用します。残念ながら、2 つの状態間で任意の値をコピーする方法がないため、テーブルをアンロールする必要があります。

関数のコピーは特に困難です。そのためにレジストリを使用している場合は、保存に使用した状態を追跡し、元の状態で実行して、効果的に状態間の呼び出しに変換することをお勧めします。関数の移動の。

于 2009-04-06T04:14:49.830 に答える
3

名前が示すように、 luaL_newstate() は別の分離された状態を作成します。レジストリは lua_newthread(parent_state); で作成された「スレッド」間でのみ共有されます。

質問の編集に合わせて編集します。

スクリプトは同じ状態で実行できますが、それが望ましくない場合は、2 つの状態間でデータを同期するための独自のメカニズムを提供する必要があります。

于 2009-04-06T01:06:44.710 に答える
2

複数のLuaユニバース(州)を使用するには、 LuaLanesを一見の価値があります。マルチステートLuaソリューションの大まかな比較もあります。

レーンは実際にハビエルが言及する「隠された状態」を提供します。また、そのような共有データにアクセスするために必要なロックと、そのようなデータが変更されるのを待つ機能も処理します。また、アプリケーションの状態と非表示の状態の間でコピー可能なもの(関数やクロージャーを含む)をすべてコピーします。

于 2009-04-06T15:29:58.270 に答える