2017-05-09 44 views
2

我正在研究Lua中的深度学习任务,并且需要从C++将图像流导入到Lua中。 C++脚本正在从共享内存中读取数据,并且我有指向C++中图像的指针。我想在Lua中得到这个指针,并将图像流传给我的神经网络。
由于Lua不使用指针,并且就我的研究而言,要将此指针包装到用户数据中并写入访问器方法。正如在User Data With Pointer Example中所解释的那样。
我的问题是我需要用原始像素数据提供神经网络,到目前为止,网上提供的资料表明,数据处理应该用C++完成,并且无法直接在Lua中获取该对象。
这里应该是什么正确的方法?我如何从C++中的指针获取Lua中的对象值?通过从C++导入图像指针在Lua中处理图像流

回答

2

那么,你必须让数据可以访问到Lua 的一些的方式。

我能想到的四种一般方法:

  1. 转换数据

    • 写作C(++)代码横穿所述数据以创建一个Lua数据 结构制成的表&原始值(布尔值,数字, 字符串)
    • 将数据转换为交换格式(JSON,CBOR,......或在 情况下的图像数据: PNM/PAM)为其 你对双方的代码,也可以平凡写

    (我就不再多说了这些选项在这里。)

  2. 在将它作为用户数据和写入存取器函数,所以可以(++)

  3. (仅用于免费指针的数据写在Lua而不是C的转换代码和图片通常是)将原始数据区域作为字符串传递给Lua

  4. (LuaJIT只)使用ffi.cdef声明匹配的内存格式免费访问&转换是c struct S(整型,浮点,并不重要 - 也可以用指针工作)

(2)基本上只是(1a),大部分代码都转移到了Lua端。 (3)与免费存取码相同(string.byte(data, i[, j])和其他一些新增加的5.3:string.unpack(fmt, data[, startpos]))。

在决定采用其中一种方法之前,先看看对方想要的格式。

也许你的数据已经是这种格式,在这种情况下,你只需要以某种方式路由指针。 (也许有一个函数接受一个Lua表,但也许还有一个函数接受一个字符串或指向原始图像数据的指针。)如果适用,使用(light)用户数据或字符串进行通信。(这可能是最快的,如果这种传递数据的方式不存在,还可以考虑询问上游是否可以添加数据。)

如果失败,则必须实际触摸数据。字符串版本可能是最简单的,但也可能是最慢的。 (如果数据是一个连续的字节块,你可以简单地使用lua_pushlstring 将所有内容都写入Lua中,但是这会创建Lua内部的“字符串”的一个副本,可能相对较慢)。之后,可以使用Lua的standard string handling functionality

如果您使用的是LuaJIT,那么使用ffi库可能是一个好主意。你可能需要的一个非常简短的概要(使用链表为例):

ffi = require "ffi" 
-- sample structure, yours will differ 
ffi.cdef [[ 
    typedef struct Node_s { struct Node_s *next; int value; } Node; 
]] 

-- in your case you will get a pointer from C, which you can then 
-- ffi.cast("Node*", ptr) 
-- after that, you can access the fields (ptr.next, ptr.value etc.) 
-- we'll just use some dummy sample data here: 
do 
    local p = ffi.new("Node") 
    local q = ffi.new("Node") 
    p.next = q 
    p.value, p.next.value = 23, 42 
    ptr = tonumber(tostring(p):match(": (0x%x*)")) 
end 

data = ffi.cast("Node*", ptr) 
print("first value:", data.value) 
--> first value: 23 
print("second value:", data.next.value) 
--> second value: 42 
print("third value:", data.next.next.value) 
--> Segmentation fault [so be just as careful as you're in C(++)!] 

最后,如果你对香草的Lua,您可能需要使用(全)用户数据和手工编写的存取,以避免数据复制造成的速度损失。 (完整的用户数据是必需的,所以你可以设置一个metatable来获得访问者,但它可以简单地指向你的外部分配的数据。)“Lua编程”一书有很好的信息(第一版在线,direct link to the relevant chapter

+0

非常感谢你这么详细的回答。我正在尝试使用LuaJIT FFI,由于某些原因,我的演示代码不能提供所需的输出。 [我的C代码。](https://gist.github.com/waleedahmedrana/40af2196d72027af6d5d173a49371532) [我的Lua代码](https://gist.github.com/waleedahmedrana/86dcccb50181ce5f88702a45bfa8ee95) 输出应该是“C编程“ 但它给了我cdata :0x7ff59b084040 我在这里做错了什么? – Waleed

+0

@Waleed那么,你声明&得到了一个'char'指针(或数组)。它不能被自动翻译成一个Lua字符串,因为这会使其无法修改。 (在Lua中总是会创建一个新的字符串,所以旧的会保持不变,如果你试图通过这个内存区域进行通信,那就不好)。访问单个字节(快速,不复制等)或者使用[ ffi.string'](http://luajit.org/ext_ffi_api.html#ffi_string)创建一个正常的Lua字符串。 – nobody

+0

谢谢。这有效! – Waleed