¿Cómo puedo usar una biblioteca C ++ de node.js?

Respuestas:

66

Mira nodo-ffi .

node-ffi es un complemento de Node.js para cargar y llamar bibliotecas dinámicas usando JavaScript puro. Se puede usar para crear enlaces a bibliotecas nativas sin escribir ningún código C ++.

Vadim Baryshev
fuente
55
Diferentes compiladores de C ++ crean diferentes ABI, por lo que para usar node-ffi puede que tenga que ajustar su código de C ++ con una interfaz C, o al menos lo hice para que esto funcione en Windows con Visual Studio. Consulte stackoverflow.com/questions/2045774/… para obtener detalles sobre cómo hacer esto. ¿O debería poder usar node-ffi en C ++ sin un contenedor?
panqueque
1
Sé que ha pasado más de un año desde este comentario, pero ... ¿es posible usar bibliotecas C ++ sin un contenedor C?
Miki de Arcayne
Me encontré con problemas de compilación VS 2017/2019 con node-ffi. ¡Es una gran PITA! ¿Depende de Python 2.7 o es solo el proceso de compilación? Debe haber un mecanismo LoadLibrary en NodeJS para una DLL Win32 estándar?
tgraupmann
78

Hay una nueva respuesta a esa pregunta ahora. SWIG , a partir de la versión 3.0 parece proporcionar generadores de interfaz javascript para Node.js, Webkit y v8.

He estado usando SWIG ampliamente para Java y Python durante un tiempo, y una vez que entiendes cómo funciona SWIG, casi no hay esfuerzo (en comparación con ffi o el equivalente en el idioma de destino) necesario para conectar el código C ++ a los idiomas que SWIG Soportes.

Como un pequeño ejemplo, supongamos que tiene una biblioteca con el encabezado 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 utilizar esta clase en el nodo, simplemente escriba el siguiente archivo de interfaz SWIG (mylib.i):

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

Cree el archivo de enlace vinculante.gyp:

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

Ejecute los siguientes comandos:

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

Ahora, ejecutando el nodo desde la misma carpeta, puede hacer:

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

Aunque necesitábamos escribir 2 archivos de interfaz para un ejemplo tan pequeño, tenga en cuenta que no tuvimos que mencionar el MyClassconstructor ni el sayHellométodo en ninguna parte, SWIG descubre estas cosas y genera automáticamente interfaces naturales.

enobayram
fuente
2
Después de jugar un poco con swig / node.js, parece que swig no puede manejar funciones de C ++ que devuelven matrices (más precisamente: funciones que devuelven punteros a las matrices). Es decir, parece que no puede construir una función en C ++ que devuelva algo así como una matriz de JavaScript y que Swig la convierta automáticamente para usted.
George
55
@George SWIG es una herramienta increíble, pero no es mágica, y no es una IA general que puede comprender la semántica de su código C ++ y generar una interfaz respectiva. Por favor, preste atención a cómo la semántica, los conceptos de propiedad y la administración de por vida de C ++ y javascript son fundamentalmente diferentes.
enobayram
3
Por lo tanto, puede ver SWIG de dos maneras: es una herramienta que puede hacer lo que puede hacer de manera inmediata y cumplir con sus reglas. Eso significa que no debe esperar ver que las matrices de JavaScript salgan de las funciones de C ++ que devuelven las matrices. Lo que puede hacer es envolver su función en C ++ para que devuelva un objeto que se comporte como una matriz ( std::vector<>por ejemplo, solo %include "std_vector.i"), y podrá manipularlo en el lado de JavaScript de una manera algo incómoda. Tenga en cuenta que este enfoque sigue siendo mucho más fácil y seguro que escribir FFI usted mismo.
enobayram
3
La otra forma en que puede usar SWIG es comprender la maquinaria que se encuentra debajo. Pase unos meses usándolo, conozca sus características en profundidad. Luego puede hacer que genere la interfaz que USTED desea. Desea que devuelva una matriz de JavaScript para una matriz de C ++, bien, puede hacerlo, pero primero debe aprender cómo expresar la semántica exacta que espera en dicha interfaz y asegurarse de que se corresponda bien con su dominio problemático.
enobayram
3
De cualquier manera, le recomiendo que comience con el primer enfoque y refine su uso de SWIG en el camino. Es bastante inspirador estudiar qué hace SWIG a su código y cómo puede manipularlo.
enobayram
11

Puede usar emscripten para compilar código C ++ en js.

N3UR0CHR0M
fuente
16
Esta sería una mala idea si el objetivo del OP es obtener los beneficios de rendimiento de C ++ compilado, y para ser pedante no responde la pregunta.
Greg
77
@Greg, pero aún así es una idea que vale la pena considerar. La gente viene a esta página para buscar varios tipos de proyectos. Creo que Emscripten es una buena opción cuando tienes la base de código C / C ++ y solo quieres usarla en Nodejs.
AlexStack
1
- si el objetivo del OP es obtener los beneficios de rendimiento de C ++ compilado - Algunos de los beneficios se traducen con emscripten, particularmente con WASM: sin sobrecarga de GC, menos análisis y sobrecarga de JIT, enteros nativos, optimizaciones AOT.
ArtemGr
2

Hay nuevas formas de conectar Node.js y C ++. Por favor, saquea a Nan .

EDITAR La forma más rápida y fácil es nbind . Si desea escribir un complemento asincrónico, puede combinar la Asyncworkerclase de nan.

Jasurbek Nabijonov
fuente
1

Aquí hay un artículo interesante sobre cómo llevar su C ++ a la web con Node.js

Tres formas generales de integrar código C ++ con una aplicación Node.js, aunque hay muchas variaciones dentro de cada categoría:

  1. Automatización: llame a su C ++ como una aplicación independiente en un proceso secundario.
  2. Biblioteca compartida: empaquete sus rutinas C ++ en una biblioteca compartida (dll) y llame a esas rutinas desde Node.js directamente.
  3. Complemento Node.js: compile su código C ++ como un módulo / complemento Node.js nativo.
sreepurna
fuente
0

Con éxito con swig y C ++: http://www.swig.org/Doc1.3/SWIG.html#SWIG_nn8

No se recomienda ejecutar SWIG en archivos fuente C ++ (lo que aparecería en un archivo .C o .cxx). Aunque SWIG puede analizar las declaraciones de clase C ++, ignora las declaraciones que están desacopladas de su definición de clase original (las declaraciones se analizan, pero se pueden generar muchos mensajes de advertencia). Por ejemplo:

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

Rara vez se tiene una clase C ++ limitada a un solo archivo .h.

Además, las versiones de swig que admiten JavaScript son swig-3.0.1 o posterior.

Anton
fuente
No entiendo qué haría SWIG con la definición de foo::bartodos modos. La definición de un miembro de la clase tiene que ver con la implementación; Los contenedores que genera SWIG tienen que ver con la interfaz.
enobayram