Como posso usar uma biblioteca C ++ no node.js?

Respostas:

66

Veja o node-ffi .

node-ffi é um complemento do Node.js. para carregar e chamar bibliotecas dinâmicas usando JavaScript puro. Ele pode ser usado para criar ligações para bibliotecas nativas sem escrever nenhum código C ++.

Vadim Baryshev
fonte
5
Compiladores C ++ diferentes criam ABIs diferentes; portanto, para usar o node-ffi, talvez seja necessário agrupar seu código C ++ com uma interface C - ou pelo menos eu fiz isso para que isso funcionasse no Windows com o Visual Studio. Consulte stackoverflow.com/questions/2045774/… para obter detalhes sobre como fazer isso. Ou devo usar o node-ffi no C ++ sem um wrapper?
Panqueca 28/05
1
Eu sei que faz mais de um ano desde esses comentários, mas ... é possível usar libs C ++ sem um wrapper C?
Miki de Arcayne
Encontrei problemas de compilação do VS 2017/2019 com o node-ffi. É uma grande PITA! É dependente do Python 2.7 ou é apenas o processo de compilação? Deve haver um mecanismo LoadLibrary no NodeJS para uma DLL Win32 padrão?
tgraupmann
78

Há uma nova resposta para essa pergunta agora. SWIG , a partir da versão 3.0, parece fornecer geradores de interface javascript para Node.js, Webkit e v8.

Eu uso o SWIG extensivamente para Java e Python há algum tempo e, depois de entender como o SWIG funciona, quase não há esforço (comparado ao ffi ou o equivalente na linguagem de destino) necessário para fazer a interface do código C ++ com as linguagens que o SWIG apoia.

Como um pequeno exemplo, digamos que você tenha uma biblioteca com o cabeçalho 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;
        }
};

Para usar esta classe no nó, basta escrever o seguinte arquivo de interface SWIG (mylib.i):

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

Crie o arquivo de ligação binding.gyp:

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

Execute os seguintes comandos:

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

Agora, executando o nó da mesma pasta, você pode:

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

Embora precisássemos escrever 2 arquivos de interface para um exemplo tão pequeno, observe como não precisamos mencionar o MyClassconstrutor nem o sayHellométodo em nenhum lugar, o SWIG descobre essas coisas e gera automaticamente interfaces naturais.

enobayram
fonte
2
Depois de jogar um pouco com swig / node.js, parece que o swig não consegue lidar com funções C ++ que retornam matrizes (mais precisamente: funções que retornam ponteiros para matrizes). Ou seja, parece que você não pode criar uma função em C ++ que retorne algo como uma matriz JavaScript e que o swig a converta automaticamente para você.
George
5
O @George SWIG é realmente uma ferramenta incrível, mas não é mágica, e não é uma IA geral que possa entender a semântica do seu código C ++ e gerar uma interface respectiva. Por favor, preste atenção em como a semântica de C ++ e javascript, os conceitos de propriedade e o gerenciamento da vida útil são fundamentalmente diferentes.
22416 enobayram
3
Assim, você pode visualizar o SWIG de duas maneiras: É uma ferramenta que pode fazer o que pode fazer imediatamente e seguir suas regras. Isso significa que você não deve esperar a exibição de matrizes javascript nas funções C ++ que retornam matrizes. O que você pode fazer é agrupar sua função no C ++ para que ele retorne um objeto que se comporte como uma matriz ( std::vector<>por exemplo, apenas %include "std_vector.i"), e você poderá manipulá-la no lado do javascript de uma maneira um tanto estranha. Observe que essa abordagem ainda é muito mais fácil e segura do que você mesmo escrever a FFI.
22416 enobayram
3
A outra maneira de usar o SWIG é entender as máquinas abaixo. Passe alguns meses usando-o, aprenda seus recursos em profundidade. Então você pode gerar a interface que você deseja. Você deseja que ele retorne uma matriz javascript para uma matriz C ++, tudo bem, você pode fazê-lo, mas primeiro você deve aprender a expressar a semântica exata que você espera em uma interface e certificar-se de que seja bem mapeada para o domínio do seu problema.
enobayram
3
De qualquer forma, recomendo que você comece com a primeira abordagem e refine o uso do SWIG no caminho. É bastante inspirador estudar o que o SWIG faz com o seu código e como você pode manipulá-lo.
22416 enobayram
11

Você pode usar o emscripten para compilar o código C ++ em js.

N3UR0CHR0M
fonte
16
Seria uma má idéia se o objetivo do OP fosse obter os benefícios de desempenho do C ++ compilado e, para ser pedante, ele não responde à pergunta.
Greg
7
@ Greg, mas ainda é uma idéia que vale a pena considerar. As pessoas vêm a esta página para vários tipos de projetos em mãos. Eu acho que o Emscripten é uma boa opção quando você tem a base de código C / C ++ e quer apenas usá-lo no Nodejs.
AlexStack
1
- se o objetivo do OP é obter os benefícios de desempenho do C ++ compilado - Alguns dos benefícios são traduzidos com emscripten, principalmente com WASM: sem sobrecarga de GC, menos análise e sobrecarga de JIT, números inteiros nativos, otimizações de AOT.
ArtemGr 08/07/19
2

Existem novas maneiras de conectar o Node.js e o C ++. Por favor, saqueie na Nan .

EDIT A maneira mais rápida e fácil é nbind . Se você deseja escrever um complemento assíncrono, pode combinar a Asyncworkerclasse de nan.

Jasurbek Nabijonov
fonte
1

Aqui está um artigo interessante sobre como obter seu C ++ na Web com o Node.js

três maneiras gerais de integrar o código C ++ com um aplicativo Node.js. - embora haja muitas variações dentro de cada categoria:

  1. Automação - chame seu C ++ como um aplicativo independente em um processo filho.
  2. Biblioteca compartilhada - empacote suas rotinas C ++ em uma biblioteca compartilhada (dll) e chame essas rotinas diretamente do Node.js.
  3. Node.js Addon - compile seu código C ++ como um módulo / addon nativo do Node.js.
sreepurna
fonte
0

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

A execução de SWIG em arquivos de origem C ++ (o que apareceria em um arquivo .C ou .cxx) não é recomendada. Embora o SWIG possa analisar declarações de classe C ++, ele ignora as declarações dissociadas de sua definição de classe original (as declarações são analisadas, mas muitas mensagens de aviso podem ser geradas). Por exemplo:

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

É raro ter uma classe C ++ limitada a apenas um arquivo .h.

Além disso, as versões do swig que suportam JavaScript são swig-3.0.1 ou posterior.

Anton
fonte
Eu não entendo o que SWIG faria com a definição de foo::barqualquer maneira. A definição de um membro da classe tem tudo a ver com implementação; os wrappers que o SWIG gera são todos sobre a interface.
22417 enobayram