準備
- まずは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));