LoginSignup
2
6

More than 5 years have passed since last update.

node.js でc++ライブラリを動かすまで

Last updated at Posted at 2018-09-08

準備

  • まずはnode.jsをインストール
  • node.jsの拡張モジュールnode-gypをインストール
    npm install node-gyp 
  • nativeのライブラリを読み込むためのモジュール node-ffiをインストール
npm install node-ffi

ソースコード

C++


#ifdef __cplusplus
extern "C" {
#endif
  int my_func1(int x){
  cout << "here is my_func1 in C++\n";
  return x * 2;
  }
}

#ifdef __cplusplus
extern "C" {
#endif
void my_func2(const char* x1){

    cout << "here is my_func2 in C++\n";

    string x1_conv = string(x1);
    string x2 = "+ C++(str2)";
    string x3 = x1_conv + x2;
    cout << x3 << "\n";

    }
}

#ifdef __cplusplus
extern "C" {
#endif
char* my_func3(const char* x1){

    cout << "here is my_func3 in C++\n";

    const char* x2 = "+ C++(str3)";
    size_t x1_len = strlen(x1) + 1;
    size_t x2_len = strlen(x2) + 1;
    char* x3;
    x3 = (char *)malloc(x1_len + x2_len);
    sprintf(x3, "%s %s\n", x1, x2);

    return x3;
}
}

typedef struct tag_my_struct{
    int x;
    int y;
    char* s;

}my_struct;

#ifdef __cplusplus
extern "C" {
#endif
void my_func4(my_struct* ms){

    cout << "here is my_func4 in C++\n";
    cout << "x: " << ms->x << '\n';
    cout << "y: " << ms->y << '\n';
    cout << "s: " << ms->s << '\n';
    cout << "s add:" << ms->s << '\n';
    printf("C++ ms add: %p\n", ms);
    printf("C++ s add:%p\n", ms->s);
}
}

Node.js

node.js
var ffi = require('ffi')
var ref = require('ref')
var Struct = require('ref-struct')

// 構造体の定義
var my_struct = Struct({
  'x': ref.types.int,
  'y': ref.types.int,
  's': ref.refType(ref.types.char)
})

// 構造体の型を格納
var ptr_my_struct = ref.refType(my_struct);

// 構造体のポインタの型を格納
var ptr_str = ref.refType(ref.types.char);

// ffi.Libraryでライブラリ内関数の宣言
var libfactorial = ffi.Library('./c++/cmake-build-debug/libmyTest', {
  'my_func1': [ "int", [ "int" ] ],
  'my_func2': [ "void", [ "string" ] ],
  'my_func3': [ "string", [ ptr_str ] ],
  'my_func4': [ "void", [ ptr_my_struct ] ]
})

if (process.argv.length < 3) {
  console.log('Arguments: ' + process.argv[0] + ' ' + process.argv[1] + ' <max>')
  process.exit()
}

// ライブラリ内へ渡す関数の引数定義
var str2 = 'Node.js(str2)'
var str3 = 'Node.js(str3)'

// 文字列はstring型宣言ではなく、Bufferオブジェクトを渡すことでもアドレス参照される
var str3_buf = Buffer.from(str3, "utf8")

// 構造体のインスタンス
var my_struct_val = new my_struct;

// 構造体内の文字列のBuffer定義
var str4 = 'Node.js(str4)'
var str4_buf = Buffer.from(str4, "utf8")

// 構造体内の変数に値を格納
my_struct_val.x = 1000
my_struct_val.y = 2000
my_struct_val.s = str4_buf

var output1 = libfactorial.my_func1(parseInt(process.argv[2]))
console.log('Node.js output1: ' + output1)

var output2 = libfactorial.my_func2(str2)

var output3 = libfactorial.my_func3(str3_buf)
console.log('Node.js output3: ' + output3)

var output4 = libfactorial.my_func4(my_struct_val.ref())
console.log(my_struct_val.ref())
console.log('my_struct_val.s add' + ref.address(my_struct_val.s).toString(16));

2
6
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
2
6