Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to create an array of structs using ref-struct and ref-array?

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);
like image 469
dragonx Avatar asked Dec 30 '13 08:12

dragonx


People also ask

How do you create an array of structs?

To create an array of structures using the struct function, specify the field value arguments as cell arrays. Each cell array element is the value of the field in the corresponding structure array element.

Can you create an array of a struct type?

An array is a collection of data items of the same type. Each element of the array can be int, char, float, double, or even a structure. We have seen that a structure allows elements of different data types to be grouped together under a single name.

Can I use struct as array?

An array of structres in C can be defined as the collection of multiple structures variables where each variable contains information about different entities. The array of structures in C are used to store information about multiple entities of different data types.


1 Answers

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);        
    }
}
like image 171
dragonx Avatar answered Oct 07 '22 04:10

dragonx