スタンドアロンのC++アプリケーション内で数値処理を行う既存のC++コードがいくつかあります。そのコードを新しいnode.jsアプリケーション内で使用したいと思います。
Node.jsからC++コードにアクセスする方法を調べると、次の2つのオプションがあります。
node-ffiは既存のライブラリにアクセスするための良いオプションのようですが、node-ffiを使用する場合はCラッパーを作成する必要があると思いますか? C++にアクセスできるようにするには? (これは、Visual Studioを使用してWindowsで動作する簡単なテストケースを取得できる唯一の方法でした)。
ソースコードがすでにCではなくC++にある場合、上記の2つのオプションから選択する際の考慮事項は何ですか?
FFIは動的Cライブラリで動作します。これは、ダイナミックライブラリを外部に公開する必要があることを意味します。 C++では、次のようにextern "C"を使用してこれを行います。
#ifdef __cplusplus
extern "C" {
#endif
int foo (int param){
int ret = 0;
// do C++ things
return ret;
}
int bar(){
int ret = 0;
// do C++ things
return ret;
}
#ifdef __cplusplus
}
#endif
これにより、ダイナミックライブラリメソッドとして、C++関数をC-thingsで使用できるようになります。
C++ libをlibmylibrary.dll/.soとしてコンパイルした後、これをjavascriptでラップする方法は次のとおりです。
var ffi = require('ffi');
var mylibrary = ffi.Library('libmylibrary', {
"foo": [ "int", ["int"] ],
"bar": [ "int", [] ]
});
あなたができるもっとクールなことがたくさんあります。それをチェックしてください、 ここ
これがノードライブラリの場合は、メソッドをmodule.exportsに配置するだけです。同期メソッドと非同期メソッドを使用した、上記のC++コードのラップの完全な例を次に示します。
var ffi = require('ffi');
var mylibrary = ffi.Library('libmylibrary', {
"foo": [ "int", ["int"] ],
"bar": [ "int", [] ]
});
module.exports = {
fooSync : mylibrary.foo,
foo: mylibrary.foo.async,
barSync : mylibrary.bar,
bar: mylibrary.bar.async
};
node-ffi-generate は使用していませんが、この種のラッパーを生成するのはかなりクールに見えます。
このファイルをmylibrary.jsとして保存した場合、次のように使用できます。
var mylib = require('./mylibrary.js');
var num = mylib.fooSync(1);
// or
mylib.foo(1, function(er, num){
});
「いいの?」という質問も。ほとんどの場合、そう思います。メソッドをexternCにすると、他のほぼすべての言語で機能し、その一部にはFFIも含まれているため、ターゲット言語が何であれ、上記と同等の単純なものを記述します。これは、基本的な「load C++ lib」と「言語Xに適していると感じるために署名をいじくり回す」ことを除いて、維持するコードがほとんどないことを意味します。ノードに固有のものではありません。もう1つのボーナスは、一般的な共有ライブラリ(チュートリアルの例で示されているsqliteなど)です。バージョンが何であるかを正確に気にしない場合や、使用するためにコンパイルする必要があるC++コードでラップしたい場合があります。 FFIを使用すると、プリコンパイル/インストールされたlibをjavascriptだけでラップできます。