7

私は本当にこの質問をグーグルで検索しましたが、実際に解決策を得ることができませんでした。

CとLuaの間で配列を共有したいのですが、パフォーマンスのために、Luaとの間で配列をコピーすることは避けます。

そこで、CからLuaへの配列へのポインターを渡したいと思います。そして、Luaから、この配列の値を直接設定/変更したいと思います。


Cコードの例

配列を定義したい

int mydata[] = {1,2,3,4} 

Luaから。という名前でアクセスするには、グローバルに設定しますmydata


ルアで

このように値を変えたい

mydata[3] = 9

Cに戻るとmydata[3]、配列へのポインタであるため、は9です。

これはどのように可能ですか?

4

1 に答える 1

20

を介して任意のデータをLuaに公開できますuserdata。userdata値にメタテーブルを指定すると、それらのuserdataに対するさまざまな演算子/操作の動作を定義できます。array[index]この場合、配列をLuaに公開し、との場合に何をするかを定義しますarray[index] = value

配列のアドレスを保持するのに十分な大きさのuserdataバッファーを作成することにより、配列をLuaに公開します。__indexandメソッドを使用してメタテーブルを作成することにより、インデックス作成/代入の動作を定義し__newindexます。

以下は、静的配列をLuaに公開する完全な実例です。あなたのプログラムはおそらく配列をLuaに返すための他の呼び出しを持っているでしょう。境界チェックはまったくないことに注意してください。配列の境界外でインデックスを作成しようとすると、クラッシュします。これをより堅牢にするには、userdataを配列ポインターと配列サイズを持つ構造に変更して、境界チェックを実行できるようにします。

#include "lauxlib.h"

// metatable method for handling "array[index]"
static int array_index (lua_State* L) { 
   int** parray = luaL_checkudata(L, 1, "array");
   int index = luaL_checkint(L, 2);
   lua_pushnumber(L, (*parray)[index-1]);
   return 1; 
}

// metatable method for handle "array[index] = value"
static int array_newindex (lua_State* L) { 
   int** parray = luaL_checkudata(L, 1, "array");
   int index = luaL_checkint(L, 2);
   int value = luaL_checkint(L, 3);
   (*parray)[index-1] = value;
   return 0; 
}

// create a metatable for our array type
static void create_array_type(lua_State* L) {
   static const struct luaL_reg array[] = {
      { "__index",  array_index  },
      { "__newindex",  array_newindex  },
      NULL, NULL
   };
   luaL_newmetatable(L, "array");
   luaL_openlib(L, NULL, array, 0);
}

// expose an array to lua, by storing it in a userdata with the array metatable
static int expose_array(lua_State* L, int array[]) {
   int** parray = lua_newuserdata(L, sizeof(int**));
   *parray = array;
   luaL_getmetatable(L, "array");
   lua_setmetatable(L, -2);
   return 1;
}

// test data
int mydata[] = { 1, 2, 3, 4 };

// test routine which exposes our test array to Lua 
static int getarray (lua_State* L) { 
   return expose_array( L, mydata ); 
}

int __declspec(dllexport) __cdecl luaopen_array (lua_State* L) {
   create_array_type(L);

   // make our test routine available to Lua
   lua_register(L, "array", getarray);
   return 0;
}

使用法:

require 'array'

foo = array()
print(foo) -- userdata

-- initial values set in C
print(foo[1])
print(foo[2])
print(foo[3])
print(foo[4])

-- change some values
foo[1] = 2112
foo[2] = 5150
foo[4] = 777

-- see changes
print(foo[1])
print(foo[2])
print(foo[3])
print(foo[4])
于 2012-07-27T17:28:55.980 に答える