2015-09-27 85 views
0

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

更具体地说,我有一个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

为什么不简单地写这个函数到Lua read_part_of_buffer(start_offset,length,return_this_part_as_number_instead_of_string)? –

回答

1

正如您已经注意到的那样,lua_pushlstring是将原始数据以字符串形式推送到Lua的常用方法。为了避免复制,你需要将一个弱指针推向Lua,这会导致你到userdata。但如何重新解释这个用户数据在Lua作为一个字符串?短:你不能!使用LuaJIT您可以将用户数据强制转换为CData指针(您的用户数据将是一个可以保存缓冲区+大小的结构) - easy & direct。没有,你必须复制通过添加metatable到你的userdata,它允许提取作为字符串和请求大小的块。

1

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

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

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

为了确保您的需要,您必须发布您的代码。