Node.jsからC言語で書いた関数を呼び出したい。
関数は引数に構造体の配列のポインタを取る。
Node.jsからref-array-napi等を使って呼び出そうにも引数の構造体の配列を上手く渡せなくてsegmentation fault的エラーが出る。
以下のやり方でできたメモ。
参考:https://stackoverflow.com/questions/33110354/nodejs-ffi-create-array-of-struct
C言語のライブラリ側
typedef struct my_handle my_handle;
typedef struct my_xy{
double x;
double y;
} my_xy;
my_handle *my_new(const my_xy *data, uint32_t data_count) {
for (int i = 0; i < data_count; ++i) {
printf("%f, %f",data[i].x, data[i].y);
}
/* 割愛 */
return NULL;
}
これをmylib.so(またはdll)として出力して関数my_newをNode.js側から呼び出したい。
my_newの引数dataは構造体の配列。
そのためには
Node.js側
const ffi = require('ffi-napi');
const ref = require('ref-napi');
const StructType = require('ref-struct-napi');
var my_xy = StructType({
x: ref.types.double,
y: ref.types.double,
});
var buf = [];
var v0 = new my_xy;
var v1 = new my_xy;
v0.x=0.1;v0.y=0.2;
v1.x=1.1;v1.y=1.2;
buf.push(v0.ref());
buf.push(v1.ref());
var buf = Buffer.concat(buf);
const mylib = ffi.Library('./mylib.so', {
'my_new': ['pointer', ['pointer', 'uint32']],
});
var handle = mylib.my_new(buf, 2);
Node.jsで実行してみると以下の結果。
0.100000, 0.200000, 1.100000 1.200000
のはず。
##追記
もっと自然な方法があった…
Node.js側
const ffi = require('ffi-napi');
const ref = require('ref-napi');
const StructType = require('ref-struct-napi');
const ArrayType = require('ref-array-napi');
var my_xy = StructType({
x: ref.types.double,
y: ref.types.double,
});
var my_xy_array = ArrayType(my_xy);
var buf = new my_xy_array(2)
var v0 = new my_xy;
var v1 = new my_xy;
v0.x=0.1;v0.y=0.2;
v1.x=1.1;v1.y=1.2;
buf[0] = v0;
buf[1] = v1;
const mylib = ffi.Library('./mylib.so', {
'my_new': ['pointer', [my_xy_array, 'uint32']],
});
var handle = mylib.my_new(buf, 2);