我想将一个不透明的数据缓冲区从C传递给Lua而不实际复制所有数据(因为它可能是非常大的100个MB或GB)。
更具体地说,我有一个如下所示的C片段:
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);
但这不会复制数据吗?有没有办法用零拷贝(因为数据非常大)这样做?
任何帮助将不胜感激。谢谢!
答案 0 :(得分:1)
正如您已经注意到的那样,lua_pushlstring
是以字符串形式将原始数据推送到Lua的常用方法。要避免复制,您需要将弱指针推送到Lua,这会将您引导至 userdata 。但是如何将Lua中的这个用户数据重新解释为字符串呢?简:你不能!使用 LuaJIT ,您可以将用户数据转换为CData指针(您的用户数据将是一个结构,它保存您的缓冲区+大小) - 简单&直接。如果没有,则必须通过向用户数据添加元表来复制,这样可以将片段作为字符串提取并请求大小。
答案 1 :(得分:1)
最好的办法是创建一个userdata,其中包含指向缓冲区及其大小的指针,并实现一个__index
元方法,该方法允许获取单个字节并将其推送到lua。
根据您的lua脚本的详细信息,此用户数据可以用作脚本使用的字符串类型的替代品,或者您可能必须实现更多元方法,如__len
等。< / p>
如果您的脚本确实要求数据由字符串表示,那么您很可能是SOL。 Lua需要自己管理字符串中的数据,因此如果您希望它在脚本中完全表示为字符串类型,则必须将其复制到lua拥有的缓冲区。
为了确保您的需求,您必须发布您的代码。