node.jsからC ++ライブラリを使用するにはどうすればよいですか?


回答:


66

node-ffiを見てください。

node-ffiは、純粋なJavaScriptを使用して動的ライブラリをロードおよび呼び出すためのNode.jsアドオンです。C ++コードを記述せずにネイティブライブラリへのバインディングを作成するために使用できます。


5
異なるC ++コンパイラーは異なるABIを作成するため、node-ffiを使用するには、C ++コードをCインターフェースでラップする必要がある場合があります。少なくとも、これをVisual Studioを使用するWindowsで動作させるために行いました。参照stackoverflow.com/questions/2045774/...これを行う方法の詳細については、を。または、ラッパーなしでC ++でnode-ffiを使用できますか?
パンケーキ

1
このコメントから1年以上経過していることはわかっていますが、CラッパーなしでC ++ライブラリを使用できますか?
Miki de Arcayne 2013

node-ffiでVS 2017/2019のコンパイル問題に遭遇しました。メジャーなピタです!Python 2.7に依存していますか、それともビルドプロセスだけですか?標準のWin32 DLLのNodeJSにLoadLibraryメカニズムが必要ですか?
tgraupmann

78

今、その質問に対する新鮮な答えがあります。SWIG、バージョン3.0の時点でJavaScriptインターフェースジェネレーターを提供しているようです、Node.js、Webkit、およびv8用のです。

私はしばらくの間、JavaとPythonでSWIGを広範囲に使用しており、SWIGがどのように機能するかを理解すれば、C ++コードをSWIGが実行する言語とインターフェイスするために必要な作業はほとんどありません(ターゲット言語のffiまたは同等のものと比較して)。サポートしています。

小さな例として、ヘッダーがmyclass.hのライブラリがあるとします。

#include<iostream>

class MyClass {
        int myNumber;
public:
        MyClass(int number): myNumber(number){}
        void sayHello() {
                std::cout << "Hello, my number is:" 
                << myNumber <<std::endl;
        }
};

このクラスをノードで使用するには、次のSWIGインターフェースファイル(mylib.i)を記述するだけです。

%module "mylib"
%{
#include "myclass.h"
%}
%include "myclass.h"

バインディングファイルbinding.gypを作成します。

{
  "targets": [
    {
      "target_name": "mylib",
      "sources": [ "mylib_wrap.cxx" ]
    }
  ]
}

次のコマンドを実行します。

swig -c++ -javascript -node mylib.i
node-gyp build

同じフォルダからノードを実行すると、次のことができます。

> var mylib = require("./build/Release/mylib")
> var c = new mylib.MyClass(5)
> c.sayHello()
Hello, my number is:5

このような小さな例では、2つのインターフェイスファイルを作成する必要がありましたが、MyClassコンストラクターやsayHelloメソッドのどこにも言及する必要がなかったことに注意してください。SWIGがこれらを検出し、自然なインターフェイスを自動的に生成します。


2
swig / node.jsで少し遊んだ後、swigは配列を返すC ++関数(より正確には、配列へのポインターを返す関数)を処理できないようです。つまり、JavaScript配列のようなものを返す関数をC ++で作成して、swigに自動的に変換させることはできないようです。
ジョージ

5
@George SWIGは確かに素晴らしいツールですが、魔法ではありません。また、C ++コードのセマンティクスを理解してそれぞれのインターフェイスを生成できる一般的なAIではありません。C ++とJavaScriptのセマンティクス、所有権の概念、およびライフタイム管理の根本的な違いに注意してください。
enobayram 2016年

3
したがって、SWIGは2つの方法で表示できます。それは、箱から出してできることを実行できるツールであり、そのルールに従ってプレイできます。つまり、配列を返すC ++関数からJavaScript配列が飛び出すことを期待するべきではありません。代わりにできることは、C ++で関数をラップして、配列のように動作するオブジェクト(std::vector<>たとえば%include "std_vector.i")を返すようにし、JavaScript側でやや厄介な方法でそれを操作できるようにすることです。この方法は、FFIを自分で作成するよりも簡単で安全です。
enobayram 2016年

3
SWIGを使用するもう1つの方法は、その下の機構を理解することです。それを使用して数か月を費やして、その機能を深く学びます。次に、必要なインターフェイスを生成するようにできます。C ++配列のJavaScript配列を返すようにしたいのですが、できますが、そのようなインターフェースで期待する正確なセマンティクスを表現する方法を最初に学び、問題のあるドメインに適切にマップすることを確認する必要があります。
enobayram 2016年

3
どちらの方法でも、最初のアプローチから始めて、途中でSWIGの使用を改良することをお勧めします。SWIGがあなたのコードに何をするか、そしてどのようにそれを操作するかを研究することは非常に刺激的です。
enobayram 2016年


11

emscriptenを使用してC ++コードをjsにコンパイルできます。


16
コンパイルされたC ++のパフォーマンス上の利点を得ることがOPの目標であり、知識を深めることがOPの目的ではない場合、これは悪い考えです。
グレッグ

7
@Gregですが、それでも検討に値するアイデアです。このページには、さまざまな種類のプロジェクトが用意されています。Emscriptenは、C / C ++コードベースがあり、それをNodejsで使用したい場合に適しています。
AlexStack

1
- OPの目標はコンパイル済みのC ++のパフォーマンスの利点を取得する場合 -いくつかの利点の特にWASMで、emscriptenで翻訳:オーバーヘッドなしGCを、少ないオーバーヘッド、ネイティブの整数、AOTの最適化を解析し、JIT。
ArtemGr

2

Node.jsとC ++を接続する新しい方法があります。ナンで略奪してください

編集 最も速くて簡単な方法はnbindです。非同期アドオンを作成する場合はAsyncworker、nanのクラスを組み合わせることができます。


1

Node.jsを使用してC ++をWebに移行することに関する興味深い記事を以下に示します。

C ++コードをNode.jsアプリケーションと統合する3つの一般的な方法-各カテゴリには多くのバリエーションがあります。

  1. オートメーション-子プロセスでスタンドアロンアプリとしてC ++を呼び出します。
  2. 共有ライブラリ-C ++ルーチンを共有ライブラリ(dll)にパックし、それらのルーチンをNode.jsから直接呼び出します。
  3. Node.jsアドオン-C ++コードをネイティブNode.jsモジュール/アドオンとしてコンパイルします。

0

swigとC ++に注意する:http ://www.swig.org/Doc1.3/SWIG.html#SWIG_nn8

C ++ソースファイル(.Cまたは.cxxファイルに表示されるもの)でSWIGを実行することはお勧めしません。SWIGはC ++クラス宣言を解析できますが、元のクラス定義から分離された宣言は無視します(宣言は解析されますが、多くの警告メッセージが生成される可能性があります)。例えば:

/* Not supported by SWIG */
int foo::bar(int) {
    ... whatever ...
}

C ++クラスを1つの.hファイルのみに制限することはめったにありません。

また、JavaScriptをサポートするswigのバージョンはswig-3.0.1以降です。


foo::barとにかくSWIGがどう定義するのか理解できません。クラスメンバーの定義は、すべて実装に関するものです。SWIGが生成するラッパーはすべてインターフェイスに関するものです。
enobayram 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.