2017-05-09 6 views
2

저는 루아에서 깊은 학습 작업을하고 있으며 C++에서 루아로 이미지 스트림을 가져와야합니다. C++ 스크립트는 공유 메모리에서 데이터를 읽으며 C++에서 이미지 포인터를 가지고 있습니다. 루아에서이 포인터를 얻고 뉴런 네트워크에 이미지 스트림을주고 싶습니다.
루아는 포인터를 사용하지 않으므로 내 연구에서이 포인터를 userdata로 랩하고 접근 자 메소드를 작성하는 방법이 있습니다. 이 User Data With Pointer Example에 설명되어 있습니다.
내 문제는 원시 픽셀 데이터로 신경망을 먹여야하고 온라인에서 사용할 수있는 자료는 데이터 처리가 C++로 수행되어야하며 루아에서 직접 그 객체를 가져올 수있는 방법이 없다는 것입니다.
올바른 접근 방법은 무엇입니까? 루아에서 C++의 포인터로 객체 값을 얻으려면 어떻게해야합니까?루아의 이미지 스트림을 C++에서 이미지 포인터를 가져 와서 처리하십시오.

답변

2

음, 데이터를 길에 액세스 할 수 있도록 설정해야합니다. 나는 네 일반적인 접근 방식의

을 생각할 수 있습니다 :

  1. 데이터 변환

    • 쓰기 C (++) 구조로 만들어진 루아 데이터를 생성하는 데이터를 통과 코드 테이블 & 프리미티브 값 (부울 값, 숫자, 문자열)
    • 데이터를 교환 형식으로 변환 (JSON, CBOR, ... 또는 이미지 데이터의 경우 : PNM/PAM)는 양쪽에 코드를하거나 하찮게 그것을

  2. 을 기록 할 수있는 을 위해 (내가 여기 더 이상 이러한 옵션에 대한 말을하지 않습니다 .) 당신이 (++)

  3. (단지 포인터 프리 데이터 대신 C의 루아의 변환 코드를 작성할 수 있도록

  4. 는, 유저 데이터 및 쓰기 접근 기능으로 전달하고, 이미지는 보통 that) 원시 데이터 영역을 문자열로 루아에 전달

  5. (LuaJIT 만) 무료로 이용할 수 & 변환을위한 메모리 형식과 일치 C struct의 선언 ffi.cdef를 사용하여 (INT, 플로트, 중요하지 않습니다 - 또한 포인터로 작업 할 수 있습니다)

(2)는 근본적으로 (1a) 코드의 대부분이 루아 쪽으로 이동 한 것입니다. (3)은 무료 액세서리 코드 (string.byte(data, i[, j]))와 동일하며 5.3 : string.unpack(fmt, data[, startpos])에 새로 추가되었습니다.

이러한 접근 방식 중 하나를 결정하기 전에 상대방이 원하는 형식을 확인하십시오.

데이터가 이미 해당 형식으로되어있는 경우 포인터를 어떤 방식 으로든 사용해야 만합니다. (루아 (Lua) 테이블을 받아들이는 함수가있을 수 있지만, 원시 이미지 데이터에 대한 문자열이나 포인터를 받아들이는 함수가 있을지도 모른다.)이 경우, 사용자 데이터 또는 문자열을 사용하여 통신한다.(아마도 이것이 가장 빠를 것입니다. 데이터를 전달하는 이런 방법이 없다면 아직 추가 할 수 있는지 상류에 묻는 것을 고려해보십시오.)

실제로 데이터를 터치해야합니다. 문자열 버전은 잠재적으로 가장 쉽지만 또한 가장 느릴 수 있습니다. (데이터가 하나의 연속적인 바이트 블록 인 경우, 간단히 lua_pushlstring 을 사용하여 모든 것을 루아로 가져올 수 있지만, 상대적으로 느린 루아 상태의 "문자열"의 사본을 생성합니다.) 그 후에, 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(++)!] 

마지막으로, 당신은 피하기 위해 (전체) 유저 데이터 및 수동으로 기록 된 접근을 사용할 수 있습니다 데이터 복사로 인한 속도 손실. (전체 사용자 데이터는 접근자를 얻기 위해 메타 테이블을 설정할 수 있도록 필요하지만 단순히 외부에서 할당 된 데이터를 가리키는 포인터가 될 수 있습니다.) "Programming in Lua"에는 좋은 정보가 있습니다 (초판은 온라인, direct link to the relevant chapter입니다).)

+0

이렇게 자세한 답변을 가져 주셔서 감사합니다. 나는 LuaJIT FFI를 사용하려고 노력하고 있는데 어떤 이유로 내 데모 코드가 원하는 결과를 내지 못한다. [내 C 코드. (https://gist.github.com/waleedahmedrana/40af2196d72027af6d5d173a49371532) [내 루아 코드 (https://gist.github.com/waleedahmedrana/86dcccb50181ce5f88702a45bfa8ee95) 출력이어야 "C 프로그래밍 " 그러나 그것은 나를 제공합니다 cdata : 0x7ff59b084040 내가 뭘 잘못하고 있니? – Waleed

+0

@Waleed 글쎄, 당신은 & char 포인터 (또는 배열)를 선언 & 가지고있어. 루아 문자열로 자동 변환 될 수 없기 때문에 수정할 수 없기 때문입니다. (Lua에서는 항상 새로운 문자열을 생성하기 때문에 이전의 문자열은 변경되지 않습니다. 메모리 영역을 통해 통신하려는 경우 좋지 않습니다.) 개별 바이트 (빠른, 복사 안 함 등)에 액세스하거나 [ ffi.string'] (http://luajit.org/ext_ffi_api.html#ffi_string)을 사용하여 일반적인 루아 문자열로 복사본을 만듭니다. – nobody

+0

감사합니다. 그게 효과가있어! – Waleed