1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Node.jsからC言語で書いた関数(引数に構造体の配列)を呼ぶ

Last updated at Posted at 2022-01-01

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);

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?