LUA和C之间共享阵列 [英] Share Array between lua and C
问题描述
我真的Google搜索这个问题,但我从来没有真正得到一个解决方案。
I have really Googled this question but I never really got an solution.
我想分享C和Lua中之间的阵列,性能我会避免复制数组并从Lua。
I want to share an Array between C and Lua, for performance I will avoid copying Arrays to and from Lua.
所以我想一个指针传递从C到Lua的数组。然后从Lua我想设置/修改此数组直接值。
So I want to pass a pointer to the Array from C to Lua. And then from Lua I want to set/modify values in this array directly.
用C code示例
我想我的定义阵列
int mydata[] = {1,2,3,4}
设置全局从Lua名为 MYDATA
访问它。
在Lua中
我想改变这样的值
mydata[3] = 9
当我回到C, MYDATA [3]
是9,因为它是一个指针数组。
and when I return to C, mydata[3]
is 9 because it is a pointer to the array.
这怎么可能呢?
推荐答案
您可以通过用户数据
公开任意数据到Lua。如果你给你的用户数据值a的元表的,您可以定义这些用户数据各运营商/运营的行为。在这种情况下,我们要公开数组Lua和定义什么在数组[索引]
和数组[指数]的情况下做=值
。
You can expose arbitrary data to Lua via userdata
. If you give your userdata values a metatable, you can define the behavior for various operators/operations on those userdata. In this case, we want to expose an array to Lua and define what to do in the case of array[index]
and array[index] = value
.
我们通过创建一个用户数据缓冲区大到足以容纳数组的地址暴露数组的Lua。我们所定义的索引/转让行为创造了一个metatable中的 __指数
和 __ newindex
方法。
We expose the array to Lua by creating a userdata buffer large enough to hold the address of the array. We define the indexing/assignment behavior by created a metatable with the __index
and __newindex
methods.
下面是一个完整的,工作的例子,暴露了一个静态数组到Lua。你的程序将可能有一些其他的要求返回数组到Lua。请注意,有没有boundschecking可言;如果您尝试了数组边界以外的指数,你会崩溃。为了使这更健壮,你要更改用户数据到具有数组指针和数组的大小的结构,所以你可以做boundschecking。
Below is a complete, working example that exposes a static array to Lua. Your program will probably have some other call for returning the array to Lua. Note, there's no boundschecking at all; if you try to index outside the array bounds, you'll crash. To make this more robust, you'd want to change the userdata to a structure which has the array pointer and the array size, so you can do boundschecking.
#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])
这篇关于LUA和C之间共享阵列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!