使用ref为StructType定义双指针?

时间:2022-09-06 18:42:19

I'm using a C-library to browse the network for specific hardware. I have a struct, called EyeTracker, that contain some properties.

我正在使用C库浏览网络以获取特定硬件。我有一个名为EyeTracker的结构,它包含一些属性。

The library function is called using EyeTracker**.

使用EyeTracker **调用库函数。

From header file (C code):

来自头文件(C代码):

API Status _eyetracker_search(EyeTracker** eyetrackers, size_t eyetrackers_size, size_t* count_eyetrackers);

You are expected to allocate enough memory to fit x amount of trackers using the pointer (hope I'm making sense here).

你应该使用指针分配足够的内存以适应x数量的跟踪器(希望我在这里有意义)。

My question is: how do I write the above using javascript, ref and node-ffi?

我的问题是:如何使用javascript,ref和node-ffi编写上述内容?

I've gotten so far as to be able to get info on ONE tracker.

我已经知道能够在一个跟踪器上获取信息。

JavaScript code

let eyeTracker = StructType({ ... }),
    numberOfTrackersToGet = 10;
let eyeTrackerStructPtr = (new eyeTracker()).ref(),
    eyeTrackerStructPtrPtr = eyeTrackerStructPtr.ref();
eyetracker_search(eyeTrackerStructPtrPtr, numberOfTrackersToGet);

I need to make space to numberOfTrackersToGet pointers to a pointer to Struct of EyeTracker type.

我需要为numberOfTrackersToGet提供空间指向指向StructTracker类型的指针。

ArrayType does not seem to work.

ArrayType似乎不起作用。

2 个解决方案

#1


0  

It is not clear how the function_call works. If it expects an already allocated struct array, then it could accept just TobiiProEyeTracker*.

目前还不清楚function_call是如何工作的。如果它期望已经分配的struct数组,那么它只能接受TobiiProEyeTracker *。

If it writes the pointer of an internally allocated array to a parameter, then it would use TobiiProEyeTracker** but in this case there is no reason to write

如果它将内部分配的数组的指针写入参数,那么它将使用TobiiProEyeTracker **但在这种情况下没有理由写

You are expected to allocate enough memory ...

你应该分配足够的内存......

If the function requires a pre-allocated struct array you can use this:

如果函数需要预先分配的struct数组,则可以使用:

var ArrayType = require('ref-array')

var intPtr = ref.refType('int');
var TobiiProEyeTracker = StructType({ ... })
var tobiiEyeTrackerStructPtr = ref.refType(TobiiProEyeTracker);
var tobiiEyeTrackerStructPtrPtr = ref.refType(tobiiEyeTrackerStructPtr);

var lib = ffi.Library('libnamehere', {
  'tobii_pro_eyetracker_search': [ 'void', [ tobiiEyeTrackerStructPtrPtr, 'int', intPtr ] ]
});

var numberOfTrackersToGet = 10
var tobiiEyeTrackerStructArray = ArrayType(TobiiProEyeTracker, numberOfTrackersToGet)
var TobiiProEyeTrackerSize = ...
var countPtr = ref.alloc('int'); // allocate a pointer to int

lib.tobii_pro_eyetracker_search(tobiiEyeTrackerStructArray.ref(), TobiiProEyeTrackerSize, countPtr);

var count = countPtr.deref();

#2


0  

This is what ended up working, I'm sure it can be approved.

这是最终工作,我相信它可以被批准。

let EyeTracker = StructType({ ... fields are visible below })
let dummyCount = ref.alloc("int", 0),
    count = 5,
    tempArray = [],
    buff = Buffer.alloc(count * ref.ref(dummyCount).byteLength),
    pointerSize = ref.ref(dummyCount).byteLength; // byteLength should give the size of a pointer
    _eyetracker_search.async(buff, count, dummyCount, (err, status) => {
    for (let i = 0, len = buff.length; i < len; i += pointerSize) {
        let p = ref.readPointer(buff, i, EyeTracker.size),
            offset = 0,
            struct = new EyeTracker({
                uri: ref.readCString(ref.readPointer(p, offset)),
                device_name: ref.readCString(ref.readPointer(p, (offset += pointerSize))),
                serial_number: ref.readCString(ref.readPointer(p, (offset += pointerSize))),
                model: ref.readCString(ref.readPointer(p, (offset += pointerSize))),
                generation: ref.readCString(ref.readPointer(p, (offset += pointerSize))),
                firmware_version: ref.readCString(ref.readPointer(p, (offset += pointerSize)))
           });
           tempArray.push(struct);
       }
   });

#1


0  

It is not clear how the function_call works. If it expects an already allocated struct array, then it could accept just TobiiProEyeTracker*.

目前还不清楚function_call是如何工作的。如果它期望已经分配的struct数组,那么它只能接受TobiiProEyeTracker *。

If it writes the pointer of an internally allocated array to a parameter, then it would use TobiiProEyeTracker** but in this case there is no reason to write

如果它将内部分配的数组的指针写入参数,那么它将使用TobiiProEyeTracker **但在这种情况下没有理由写

You are expected to allocate enough memory ...

你应该分配足够的内存......

If the function requires a pre-allocated struct array you can use this:

如果函数需要预先分配的struct数组,则可以使用:

var ArrayType = require('ref-array')

var intPtr = ref.refType('int');
var TobiiProEyeTracker = StructType({ ... })
var tobiiEyeTrackerStructPtr = ref.refType(TobiiProEyeTracker);
var tobiiEyeTrackerStructPtrPtr = ref.refType(tobiiEyeTrackerStructPtr);

var lib = ffi.Library('libnamehere', {
  'tobii_pro_eyetracker_search': [ 'void', [ tobiiEyeTrackerStructPtrPtr, 'int', intPtr ] ]
});

var numberOfTrackersToGet = 10
var tobiiEyeTrackerStructArray = ArrayType(TobiiProEyeTracker, numberOfTrackersToGet)
var TobiiProEyeTrackerSize = ...
var countPtr = ref.alloc('int'); // allocate a pointer to int

lib.tobii_pro_eyetracker_search(tobiiEyeTrackerStructArray.ref(), TobiiProEyeTrackerSize, countPtr);

var count = countPtr.deref();

#2


0  

This is what ended up working, I'm sure it can be approved.

这是最终工作,我相信它可以被批准。

let EyeTracker = StructType({ ... fields are visible below })
let dummyCount = ref.alloc("int", 0),
    count = 5,
    tempArray = [],
    buff = Buffer.alloc(count * ref.ref(dummyCount).byteLength),
    pointerSize = ref.ref(dummyCount).byteLength; // byteLength should give the size of a pointer
    _eyetracker_search.async(buff, count, dummyCount, (err, status) => {
    for (let i = 0, len = buff.length; i < len; i += pointerSize) {
        let p = ref.readPointer(buff, i, EyeTracker.size),
            offset = 0,
            struct = new EyeTracker({
                uri: ref.readCString(ref.readPointer(p, offset)),
                device_name: ref.readCString(ref.readPointer(p, (offset += pointerSize))),
                serial_number: ref.readCString(ref.readPointer(p, (offset += pointerSize))),
                model: ref.readCString(ref.readPointer(p, (offset += pointerSize))),
                generation: ref.readCString(ref.readPointer(p, (offset += pointerSize))),
                firmware_version: ref.readCString(ref.readPointer(p, (offset += pointerSize)))
           });
           tempArray.push(struct);
       }
   });