Come posso usare una libreria C ++ da node.js?


Risposte:


66

Guarda node-ffi .

node-ffi è un addon Node.js per caricare e chiamare librerie dinamiche usando JavaScript puro. Può essere utilizzato per creare collegamenti a librerie native senza scrivere alcun codice C ++.


5
Diversi compilatori C ++ creano ABI diversi, quindi per usare node-ffi potresti dover avvolgere il tuo codice C ++ con un'interfaccia C - o almeno ho fatto farlo funzionare su Windows con Visual Studio. Consulta stackoverflow.com/questions/2045774/… per i dettagli su come eseguire questa operazione. O dovrei essere in grado di usare node-ffi su C ++ senza un wrapper?
pancake,

1
So che è passato più di un anno da questi commenti, ma ... è possibile usare le librerie C ++ senza un wrapper C?
Miki de Arcayne,

Ho incontrato VS 2017/2019 problemi di compilazione con node-ffi. È un grande PITA! Dipende da Python 2.7 o è solo il processo di compilazione? È necessario un meccanismo LoadLibrary in NodeJS per una DLL Win32 standard?
tgraupmann,

78

C'è una nuova risposta a questa domanda ora. SWIG , dalla versione 3.0 sembra fornire generatori di interfaccia javascript per Node.js, Webkit e v8.

Ho usato SWIG ampiamente per Java e Python per un po ', e una volta capito come funziona SWIG, non c'è quasi nessuno sforzo (rispetto a ffi o l'equivalente nella lingua di destinazione) necessario per interfacciare il codice C ++ con le lingue che SWIG supporti.

Ad esempio, supponiamo di avere una libreria con l'intestazione 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;
        }
};

Per utilizzare questa classe nel nodo, è sufficiente scrivere il seguente file di interfaccia SWIG (mylib.i):

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

Creare il file di associazione binding.gyp:

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

Esegui i seguenti comandi:

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

Ora, eseguendo il nodo dalla stessa cartella, puoi fare:

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

Anche se abbiamo bisogno di scrivere 2 file di interfaccia per un esempio così piccolo, notare come non abbiamo dovuto menzionare il MyClasscostruttore né il sayHellometodo da nessuna parte, SWIG scopre queste cose e genera automaticamente interfacce naturali.


2
Dopo aver giocato con swig / node.js per un po ', sembra che swig non sia in grado di gestire le funzioni C ++ che restituiscono array (più precisamente: funzioni che restituiscono puntatori ad array). Cioè, sembra che non sia possibile creare una funzione in C ++ che restituisca qualcosa come un array JavaScript e che il swig lo converta automaticamente per te.
George,

5
@George SWIG è davvero uno strumento straordinario, ma non è magico e non è un AI generale che può capire la semantica del tuo codice C ++ e generare una rispettiva interfaccia. Si prega di prestare attenzione a come la semantica di C ++ e javascript, i concetti di proprietà e la gestione della vita sono fondamentalmente diversi.
enobayram,

3
Quindi puoi visualizzare SWIG in due modi: è uno strumento che può fare ciò che può fare immediatamente e giocare secondo le sue regole. Ciò significa che non dovresti aspettarti di vedere gli array javascript che escono dalle funzioni C ++ che restituiscono gli array. Quello che puoi invece fare è avvolgere la tua funzione in C ++ in modo che restituisca un oggetto che si comporta come un array ( std::vector<>per esempio, solo %include "std_vector.i") e sarai in grado di manipolarlo sul lato javascript in un modo un po 'strano. Si noti che questo approccio è ancora molto più semplice e sicuro rispetto alla scrittura di FFI da soli.
enobayram,

3
L'altro modo in cui puoi usare SWIG è capire i macchinari sottostanti. Trascorri qualche mese ad usarlo, scopri le sue caratteristiche in profondità. Quindi puoi farlo generare l'interfaccia che desideri. Vuoi che restituisca un array javascript per un array C ++, va bene, puoi farlo, ma dovresti prima imparare come esprimere la semantica esatta che ti aspetti in tale interfaccia e assicurarti che si associ bene al tuo dominio problematico.
enobayram,

3
Ad ogni modo, ti consiglio di iniziare con il primo approccio e perfezionare il tuo utilizzo di SWIG lungo la strada. È abbastanza stimolante studiare cosa fa SWIG al tuo codice e come puoi manipolarlo.
enobayram,


11

È possibile utilizzare emscripten per compilare il codice C ++ in js.


16
Questa sarebbe una cattiva idea se l'obiettivo dell'OP è quello di ottenere i benefici in termini di prestazioni del C ++ compilato, ed essere pedante non risponde alla domanda.
Greg,

7
@Greg ma comunque è un'idea che vale la pena considerare. Le persone vengono su questa pagina per vari tipi di progetti in mano. Penso che Emscripten sia una buona opzione quando hai la base di codice C / C ++ e vuoi solo usarla in Nodejs.
AlexStack,

1
- se l'obiettivo del PO è quello di ottenere i vantaggi in termini di prestazioni del C ++ compilato - Alcuni dei vantaggi si traducono in emscripten, in particolare con WASM: nessun sovraccarico GC, meno costi di analisi e JIT, interi nativi, ottimizzazioni AOT.
ArtemGr

2

Ci sono modi più recenti per connettere Node.js e C ++. Per favore, saccheggia Nan .

MODIFICARE Il modo più semplice e veloce è nbind . Se vuoi scrivere un componente aggiuntivo asincrono puoi combinare Asyncworkerclasse da nan.


1

Ecco un interessante articolo su Come portare il tuo C ++ sul Web con Node.js

tre modi generali per integrare il codice C ++ con un'applicazione Node.js, sebbene ci siano molte varianti all'interno di ciascuna categoria:

  1. Automazione: chiama il tuo C ++ come app autonoma in un processo figlio.
  2. Libreria condivisa: impacchettare le routine C ++ in una libreria condivisa (dll) e chiamare direttamente tali routine da Node.js.
  3. Componente aggiuntivo Node.js: compila il codice C ++ come modulo / componente aggiuntivo Node.js nativo.

0

Diventato con swig e C ++: http://www.swig.org/Doc1.3/SWIG.html#SWIG_nn8

Non è consigliabile eseguire SWIG su file sorgente C ++ (ciò che apparirebbe in un file .C o .cxx). Anche se SWIG può analizzare le dichiarazioni di classe C ++, ignora le dichiarazioni che sono disaccoppiate dalla loro definizione di classe originale (le dichiarazioni vengono analizzate, ma possono essere generati molti messaggi di avviso). Per esempio:

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

Raramente è necessario avere una classe C ++ limitata a un solo file .h.

Inoltre, le versioni di swig che supportano JavaScript sono swig-3.0.1 o successive.


Non capisco cosa farebbe SWIG con la definizione di foo::bar. La definizione di un membro della classe riguarda l'implementazione; i wrapper generati da SWIG riguardano l'intera interfaccia.
enobayram,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.