将只读缓冲区从 C 传递到 Lua。

我想在不复制所有数据的情况下,将一个不透明的数据缓冲区从C传递到Lua(因为它可能非常大,100多兆字节或几千兆字节)。

更具体地说,我有一个C片段,看起来像这样:

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

我的C程序不知道缓冲区中数据的结构。它完全对此毫不知情。它除了调用负责消耗此数据的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新手:C-Lua如何从C向Lua传递结构/缓冲区?。但是,该线程中的解决方案是:“使用LuaJIT”,这对我来说没有任何意义。

潜在的解决方案是使用:

lua_pushlstring (L, buffer, size);

但是,这不会复制数据吗?有没有一种零副本的方法可以做到这一点(因为数据很大)?

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

点赞
用户2546626
用户2546626

正如你已经注意到的那样,lua_pushlstring 是将原始数据以字符串形式推送到 Lua 的常规方法。为了避免复制,你需要推送一个弱指针到 Lua,这将带领你进入用户数据的领域。但是如何在 Lua 中重新解释这些用户数据呢?简而言之:你不能!使用 LuaJIT,你可以将用户数据转换为 CData 指针(你的用户数据将是一个结构体,其中包含你的缓冲区 + 大小)- 简单而直接。没有 LuaJIT 的情况下,你需要通过为用户数据添加元表来进行复制,这个元表允许将数据作为字符串提取出来并请求大小。

2015-09-28 02:08:21
用户3598119
用户3598119

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

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

如果您的脚本确实要求数据由字符串表示,则您很可能会遇到问题。Lua 要求在字符串中管理数据,因此如果要将其表示为脚本中的字符串类型,则必须将其复制到由 Lua 拥有的缓冲区中。

要确保你的需求,你需要发布你的代码。

2015-09-28 02:15:35