Bagaimana saya bisa menggunakan pustaka C ++ dari node.js?

Jawaban:

66

Lihatlah node-ffi .

node-ffi adalah addon Node.js untuk memuat dan memanggil pustaka dinamis menggunakan JavaScript murni. Ini dapat digunakan untuk membuat binding ke pustaka asli tanpa menulis kode C ++.

Vadim Baryshev
sumber
5
Kompiler C ++ yang berbeda membuat ABI yang berbeda, jadi untuk menggunakan node-ffi Anda mungkin harus membungkus kode C ++ Anda dengan antarmuka C - atau setidaknya saya melakukan ini untuk bekerja pada Windows dengan Visual Studio. Lihat stackoverflow.com/questions/2045774/… untuk rincian tentang cara melakukan ini. Atau haruskah saya dapat menggunakan node-ffi pada C ++ tanpa pembungkus?
panekuk
1
Saya tahu ini lebih dari setahun sejak komentar ini tetapi ... apakah mungkin untuk menggunakan lib C ++ tanpa bungkus C?
Miki de Arcayne
Saya mengalami masalah kompilasi VS 2017/2019 dengan node-ffi. Ini adalah PITA utama! Apakah ini tergantung pada Python 2.7 atau itu hanya proses pembangunan? Harus ada mekanisme LoadLibrary di NodeJS untuk Win32 DLL standar?
tgraupmann
78

Ada jawaban baru untuk pertanyaan itu sekarang. SWIG , pada versi 3.0 tampaknya menyediakan generator antarmuka javascript untuk Node.js, Webkit, dan v8.

Saya telah menggunakan SWIG secara ekstensif untuk Java dan Python untuk sementara waktu, dan begitu Anda memahami cara kerja SWIG, hampir tidak ada upaya (dibandingkan dengan ffi atau yang setara dalam bahasa target) yang diperlukan untuk menghubungkan kode C ++ ke bahasa yang SWIG mendukung.

Sebagai contoh kecil, misalkan Anda memiliki perpustakaan dengan header 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;
        }
};

Untuk menggunakan kelas ini dalam simpul, Anda cukup menulis file antarmuka SWIG berikut (mylib.i):

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

Buat file mengikat binding.gyp:

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

Jalankan perintah berikut:

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

Sekarang, menjalankan simpul dari folder yang sama, dapat Anda lakukan:

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

Meskipun kami perlu menulis 2 file antarmuka untuk contoh sekecil itu, perhatikan bagaimana kami tidak perlu menyebutkan MyClasskonstruktor atau sayHellometode di mana pun, SWIG menemukan hal-hal ini, dan secara otomatis menghasilkan antarmuka alami.

enobayram
sumber
2
Setelah bermain dengan swig / node.js sebentar, tampaknya swig tidak dapat menangani fungsi C ++ yang mengembalikan array (lebih tepatnya: fungsi yang mengembalikan pointer ke array). Yaitu, sepertinya Anda tidak dapat membangun fungsi dalam C ++ yang mengembalikan sesuatu seperti array JavaScript dan secara otomatis swig mengubahnya untuk Anda.
George
5
@ George SWIG memang alat yang luar biasa, tapi itu bukan sihir, dan itu bukan AI umum yang dapat memahami semantik kode C ++ Anda dan menghasilkan antarmuka masing-masing. Harap perhatikan bagaimana semantik C ++ dan javascript, konsep kepemilikan dan manajemen seumur hidup secara mendasar berbeda.
enobayram
3
Jadi Anda dapat melihat SWIG dalam dua cara: Ini adalah alat yang dapat melakukan apa yang bisa dilakukan di luar kotak, dan bermain sesuai aturannya. Itu berarti, Anda seharusnya tidak berharap melihat javascript array keluar dari fungsi C ++ yang mengembalikan array. Yang bisa Anda lakukan adalah membungkus fungsi Anda dalam C ++ sehingga mengembalikan objek yang berperilaku seperti array ( std::vector<>misalnya, hanya %include "std_vector.i"), dan Anda akan dapat memanipulasinya di sisi javascript dengan cara yang agak canggung. Perhatikan bahwa pendekatan ini masih jauh lebih mudah dan lebih aman daripada menulis sendiri FFI.
enobayram
3
Cara lain Anda dapat menggunakan SWIG, adalah memahami mesin di bawahnya. Luangkan beberapa bulan menggunakannya, pelajari fitur-fiturnya secara mendalam. Kemudian Anda dapat membuatnya menghasilkan antarmuka yang Anda inginkan. Anda ingin mengembalikan array javascript untuk array C ++, baik, Anda bisa melakukannya, tetapi Anda harus terlebih dahulu belajar bagaimana mengekspresikan semantik yang tepat yang Anda harapkan dalam antarmuka seperti itu dan memastikan bahwa itu memetakan dengan baik ke domain masalah Anda.
enobayram
3
Either way, saya sarankan Anda untuk mulai dengan pendekatan pertama, dan perbaiki penggunaan SWIG di jalan. Sangat menginspirasi untuk mempelajari apa yang dilakukan SWIG terhadap kode Anda dan bagaimana Anda dapat memanipulasinya.
enobayram
11

Anda bisa menggunakan emscripten untuk mengkompilasi kode C ++ menjadi js.

N3UR0CHR0M
sumber
16
Ini akan menjadi ide yang buruk jika tujuan OP adalah untuk mendapatkan manfaat kinerja dari C ++ yang dikompilasi, dan untuk menjadi bertele-tele tidak menjawab pertanyaan.
Greg
7
@Reg tapi tetap saja itu ide yang patut dipertimbangkan. Orang-orang datang ke halaman ini untuk berbagai jenis proyek di tangan. Saya pikir Emscripten adalah pilihan yang baik ketika Anda memiliki basis kode C / C ++ dan hanya ingin menggunakannya di Nodejs.
AlexStack
1
- jika tujuan OP adalah untuk mendapatkan manfaat kinerja dari kompilasi C ++ - Beberapa manfaat diterjemahkan dengan emscripten, terutama dengan WASM: tidak ada overhead GC, lebih sedikit penguraian dan overhead JIT, bilangan bulat asli, optimalisasi AOT.
ArtemGr
2

Ada cara yang lebih baru untuk menghubungkan Node.js dan C ++. Tolong, rampas Nan .

EDIT Cara tercepat dan termudah adalah nbind . Jika Anda ingin menulis add-on asinkron Anda dapat menggabungkan Asyncworkerkelas dari nan.

Jasurbek Nabijonov
sumber
1

Berikut ini adalah artikel menarik tentang Mendapatkan C ++ ke Web dengan Node.js

tiga cara umum mengintegrasikan kode C ++ dengan aplikasi Node.js - walaupun ada banyak variasi dalam setiap kategori:

  1. Otomasi - panggil C ++ Anda sebagai aplikasi mandiri dalam proses anak.
  2. Pustaka bersama - kemas C ++ rutin Anda di pustaka bersama (dll) dan panggil rutin tersebut dari Node.js secara langsung.
  3. Addon Node.js - kompilasi kode C ++ Anda sebagai modul / addon Node.js asli.
sreepurna
sumber
0

Berhati-hatilah dengan swig dan C ++: http://www.swig.org/Doc1.3/SWIG.html#SWIG_nn8

Menjalankan SWIG pada file sumber C ++ (apa yang akan muncul dalam file .C atau .cxx) tidak disarankan. Meskipun SWIG dapat menguraikan deklarasi kelas C ++, ia mengabaikan deklarasi yang dipisahkan dari definisi kelas aslinya (deklarasi tersebut diuraikan, tetapi banyak pesan peringatan dapat dihasilkan). Sebagai contoh:

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

Jarang memiliki kelas C ++ terbatas hanya pada satu file .h.

Juga, versi swig yang mendukung JavaScript adalah swig-3.0.1 atau yang lebih baru.

Anton
sumber
Saya tidak mengerti apa yang akan dilakukan SWIG dengan definisi foo::baritu. Definisi anggota kelas adalah tentang implementasi; pembungkus yang dihasilkan SWIG adalah semua tentang antarmuka.
enobayram