8

I'm using node-ffi to call a function that takes an out-param as a pointer-to-a-pointer-to-an-array-of-structs. Is there a way to use ref-struct and ref-array for me to access the array that I get out?

struct = require("ref-struct");
var rect_type = struct({
    'x': 'int',
    'y': 'int',
    'width': 'int',
    'height': 'int',
});
var rotation_type = struct({
    'yaw': 'short',
    'pitch': 'short',
    'roll': 'short'
});
var face_type = struct({
    'rect' : rect_type,
    'rotation' : rotation_type,
    'confidence' : 'double'
});

I'm able to get the first struct, out from the pointer after the function call but I'm unable to get the rest of the array:

var mylib = ffi.Library('lib/libN', {
    'GetFaces' : [ 'int', [ 'pointer' ] ]
});

var pface_type = ref.refType(face_type);
var ppface = ref.alloc(pface_type);

result = mylib.GetFaces(ppface);

face = ppface.deref().deref();

console.log("X:" + face.rect.x + " Y:" + face.rect.y);

Is there a way to declare the parameter as an array of structs? I've tried this but it doesn't work:

var array = require("ref-array");
var face_array = array(face_type)
var p_face_array = ref.refType(face_array);
var ppface = ref.alloc(p_face_array);
result = mylib.GetFaces(ppface);
3
  • 1
    Hello. Did you find an answer on this question? Commented Feb 10, 2014 at 13:07
  • Im interested in an answer for this too. Commented Apr 28, 2014 at 20:30
  • Not really what you ask for, but maybe it could provide a hint for others who find this question on Google, since I myself spent a long time trying to figure it out. We have structs with a pointer and a length as arrays in our C library, and we also have structs with pointers to other structs and a length. Here's how I managed to retrieve it as a javascript array: pixomania.net/programming/complex-data-structures-with-node-ffi Commented Apr 14, 2015 at 7:24

1 Answer 1

3

For reference I did eventually solve this without using ref-array.

The trick/hack is to know that in C, an 'array' is pretty much the same as a pointer to the first element. So in ffi, we simply pass a pointer to the first element, and be very careful to not overstep our bounds.

var pface_type = ref.refType(face_type);
var mylib = ffi.Library('lib/libN', {
    'GetFaces' : [ 'int', [ ref.refType('int'), pface_type ] ]
});

var ppface = ref.alloc(pface_type);
var face_count = ref.alloc('int');

result = mylib.GetFaces(face_count, ppface);

var faces = [];
var count = faceCount.deref();

if(count > 0)
{
    var face_array = ppface.readPointer(0, count * face_type.size);
    var i = 0;
    for(i = 0; i < count; i++)
    {
        var face = ref.get(face_array, i * face_type.size, face_type)
        console.log("X:" + face.rect.x + " Y:" + face.rect.y);        
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.