2013-05-28 4 views
16

Ich habe einige vorhandene C++ - Code, der numerische Verarbeitung in einer eigenständigen C++ - Anwendung ausführt. Ich möchte diesen Code nun in einer neuen node.js-Anwendung verwenden.Knoten-ffi vs Knoten Erweiterung für den Zugriff auf vorhandene C++ - Funktionalität

erforscht, wie C++ für den Zugriff auf Code aus node.js, kommen zwei Optionen auf:

  1. schreiben node.js Erweiterung
  2. Verwenden node-ffi

Knoten-ffi wie ein gutes scheint Option zum Zugriff auf vorhandene Bibliotheken, aber bin ich richtig zu denken, wenn ich Node-FFI würde ich einen C-Wrapper schreiben müssen, um meine C++ zugänglich zu machen? (Dies war die einzige Möglichkeit, einen einfachen Testfall unter Windows mit Visual Studio zu erstellen).

Für meinen Fall, wo mein Quellcode bereits in C++ ist, nicht C, was sind die Überlegungen bei der Wahl zwischen den beiden oben genannten Optionen?

+0

Verwenden Sie eine Menge Vererbung, virtuelle Funktionen und Vorlagen in Ihrem Code – aaronman

+0

Keine Vorlagen. Keine virtuellen Funktionen. Einige Vererbung, obwohl ich den Code ändern könnte, um dies zu vermeiden, wenn es sein muss. – pancake

+0

Ich denke, es wäre relativ einfach, die Wrapper zu schreiben als – aaronman

Antwort

19

FFI arbeitet mit dynamischen C-Bibliotheken. Dies bedeutet, dass Sie Ihre dynamische Bibliothek extern verfügbar machen müssen. In C++, tun Sie dies mit extern "C", wie folgt aus:

#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 

Dies wird Ihre C++ Funktion zur Verfügung zu C-Dinge, als dynamische Bibliothek Methode machen.

Hier ist, wie Sie diese wickeln in JavaScript aktivieren, nachdem Sie Ihre C++ lib als libmylibrary.dll/.so zusammengestellt:

var ffi = require('ffi'); 

var mylibrary = ffi.Library('libmylibrary', { 
    "foo": [ "int", ["int"] ], 
    "bar": [ "int", [] ] 
}); 

Es gibt viele Kühler Dinge, die Sie tun können. Überprüfen Sie es, here

Wenn dies eine Knotenbibliothek ist, legen Sie einfach Ihre Methoden in module.exports. Hier ist ein vollständiges Beispiel einer Windung des oben C++ Code, mit synchronen & asynchronen Methoden:

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

ich nicht node-ffi-generate verwendet habe, aber es sieht ziemlich cool für diese Art von Wrapper für Sie erzeugen.

Wenn ich diese Datei als mylibrary.js gespeichert, ich es so verwenden könnte: „ist es besser,“

var mylib = require('./mylibrary.js'); 

var num = mylib.fooSync(1); 

// or 

mylib.foo(1, function(er, num){ 

}); 

Was die Frage der Ich denke schon, für die meisten Dinge. Wenn Sie Ihre Methoden extern C machen, werden sie in fast jeder anderen Sprache funktionieren, von denen einige auch FFI haben, so dass Sie das einfache Äquivalent des obigen in Ihrer Zielsprache schreiben würden. Dies bedeutet, dass sehr wenig Code zu pflegen ist, außer der grundlegenden "C++ lib laden", und "mit der Signatur herumspielen, um sich für Sprache X richtig zu fühlen". Es ist nicht spezifisch für Knoten. Ein weiterer Bonus ist für gemeinsame Bibliotheken (wie sqlite, im Tutorial-Beispiel gegeben). Sie interessieren sich vielleicht nicht genau, welche Version sie haben, oder wollen es mit mehr C++ - Code, der zur Verwendung kompiliert werden muss. Mit FFI können Sie eine vorkompilierte/installierte Lib mit nur Javascript umbrechen.

+0

Großartige detaillierte Antwort, vielen Dank! Es ist eine Weile her, seit ich die Frage geschrieben habe, und ich würde jetzt zustimmen, dass ich glaube, dass die Verwendung der FFI-Route einfacher ist als das Schreiben einer Erweiterung. node-ffi-generate sieht interessant aus. – pancake

Verwandte Themen