【问题标题】:Pass a read-only buffer from C to Lua将只读缓冲区从 C 传递到 Lua
【发布时间】:2015-09-28 10:15:35
【问题描述】:

我想将一个不透明的数据缓冲区从 C 传递到 Lua,而无需实际复制所有数据(因为它可能是非常大的 100 兆或 GB)。

更具体地说,我有一个如下所示的 C sn-p:

uint8_t *buffer = // points to some memory
size_t size = // size of the buffer

我的 C 程序不知道缓冲区中数据的结构。它完全没有注意到它。除了调用负责使用这些数据的 Lua 函数之外,它永远不会接触这些数据。

我的目标是将这个缓冲区传递给 Lua,然后 Lua 会解释数据的内容并基于它执行各种操作(Lua 代码知道如何根据数据的内容或大小来确定数据的结构)。此外,Lua 代码不会修改缓冲区(仅从中读取)。

以下是我理想功能的一些示例伪代码:

bool perform_action(lua_State *L, uint8_t *buffer, size_t size) {

   // Pass buffer to lua
   // call "process_buffer" function (written in Lua)
   // get return from "process_buffer" function (a boolean)
   // free(buffer);
   // return the result above
}

我认为这个问题与:lua newbie : C-Lua How to pass a struct/buffer to lua from C? 有关。但是,该线程中的解决方案是:“使用 LuaJIT”,这对我来说没有任何意义。

一个潜在的解决方案正在使用:

lua_pushlstring (L, buffer, size);

但这不会复制数据吗?有没有办法用零拷贝来做到这一点(因为数据很大)?

任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 为什么不简单地编写并将这个函数暴露给 Lua read_part_of_buffer(start_offset, length, return_this_part_as_number_instead_of_string)

标签: c lua


【解决方案1】:

正如您已经注意到的,lua_pushlstring 是将原始数据以字符串形式推送到 Lua 的常用方法。为了避免复制,您需要将一个弱指针推送到 Lua,这会将您引导到 userdata。但是如何在 Lua 中将这个 userdata 重新解释为字符串呢?短:你不能!使用 LuaJIT 您可以将 userdata 转换为 CData 指针(您的 userdata 将是一个结构,其中包含您的缓冲区 + 大小) - 简单直接。如果没有,您必须通过向用户数据添加元表来复制,该元表允许将片段提取为字符串并请求大小。

【讨论】:

    【解决方案2】:

    最好的办法是创建一个包含指向缓冲区的指针及其大小的用户数据,并实现一个__index 元方法,该方法允许获取单个字节并将其推送到 lua。

    根据您的 lua 脚本的详细信息,此用户数据可以用作脚本使用的字符串类型的直接替换,或者您可能需要实现更多元方法,如 __len 等。

    如果您的脚本确实需要用字符串表示数据,那么您很可能是 SOL。 Lua 需要自己管理字符串中的数据,因此如果您希望它在脚本中完全表示为字符串类型,则必须将其复制到 lua 拥有的缓冲区中。

    为了确定您的需求,您必须发布您的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-14
      • 2019-12-13
      • 2015-01-22
      • 2012-03-15
      • 2013-07-24
      • 2012-05-27
      • 1970-01-01
      相关资源
      最近更新 更多