【问题标题】:Share Array between lua and C在 lua 和 C 之间共享数组
【发布时间】:2012-07-26 05:03:16
【问题描述】:

我确实在谷歌上搜索过这个问题,但我从来没有真正得到解决方案。

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

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


C 代码示例

我想定义我的数组

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

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


在 Lua 中

我想像这样更改值

mydata[3] = 9

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

这怎么可能?

【问题讨论】:

  • 由于 lua 旨在作为一种可嵌入的语言与 C 很好地交互,我希望 lua 文档能够提供充足的示例。您是否已经浏览过这些信息?
  • 感谢您的快速答复。我几乎查看了所有文档,但找不到指向数组的示例。
  • 这是 Lua,不是 LUA。这不是首字母缩略词。这是一个名字。

标签: c lua lua-table


【解决方案1】:

您可以通过userdata 向 Lua 公开任意数据。如果你给你的用户数据值一个元表,你可以为这些用户数据定义各种操作符/操作的行为。在这种情况下,我们希望向 Lua 公开一个数组,并定义在 array[index]array[index] = value 的情况下要做什么。

我们通过创建一个足够大的用户数据缓冲区来将数组公开给 Lua,以保存数组的地址。我们通过使用__index__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])

【讨论】:

  • 哇,我非常感谢你这篇带有工作示例的精彩帖子。这就是我要找的,再次感谢!我是这个论坛的新手,如何给你积分?
  • 对于像我这样的初学者来说,我真的很欣赏 luabind 的易用性 - 对于您的简单问题,您会看到直接在 lua 中执行此操作需要大量代码 - 使用 luabind,基本上就是一个liner - 你应该在这里查看它是一个很棒的介绍 blog.nuclex-games.com/tutorials/cxx/luabind-introduction - 在你对事物更加熟悉之后,直接在 lua 中开发仍然更好 - 但是使用 luabind 你基本上可以非常快速地做很多事情来获得一个工作概念
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
  • 2013-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
  • 2018-03-19
相关资源
最近更新 更多