在lua和C之间共享数组

我真的用Google搜索了这个问题,但我从未真正得到过解决方案。

我想在C和Lua之间共享一个数组,为了提高性能,我将避免将数组复制到Lua和从Lua复制数组。

所以我想传递一个指向数组的指针从C到Lua。 然后从Lua我想直接在这个数组中设置/修改值。


C代码中的示例

我想定义我的数组

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

将其设置为全局以从Lua访问它,名称为mydata


在Lua

我想改变这样的值

 mydata[3] = 9 

当我返回C时, mydata[3]为9,因为它是指向数组的指针。

这怎么可能?

您可以通过userdata将任意数据暴露给Lua。 如果为userdata值提供metatable ,则可以为这些userdata上的各种运算符/操作定义行为。 在这种情况下,我们希望将一个数组暴露给Lua,并定义在array[index]array[index] = value的情况下要做什么。

我们通过创建一个足够大的userdata缓冲区来保存数组的地址,从而将数组暴露给Lua。 我们通过使用__index__newindex方法创建metatable来定义索引/赋值行为。

下面是一个完整的工作示例,它将静态数组公开给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])