Як я можу використовувати бібліотеку C ++ від node.js?


Відповіді:


66

Подивіться на node-ffi .

node-ffi - добавка Node.js для завантаження та виклику динамічних бібліотек за допомогою чистого JavaScript. З його допомогою можна створити прив’язки до рідних бібліотек без написання коду C ++.


5
Різні компілятори C ++ створюють різні ABI, тому для використання node-ffi вам, можливо, доведеться обгортати свій код C ++ інтерфейсом C - або, принаймні, мені це вдалося працювати в Windows з Visual Studio. Докладні відомості про те, як це зробити, дивіться у stackoverflow.com/questions/2045774/… . Або я повинен мати можливість використовувати node-ffi на C ++ без обгортки?
млинець

1
Я знаю, що минуло більше року з цього коментаря, але ... чи можна використовувати C ++ libs без обгортки C?
Мікі де Аркайн

Я зіткнувся з питаннями компіляції VS 2017/2019 з node-ffi. Це головний PITA! Це залежить від Python 2.7 чи це лише процес збирання? Для стандартної DL32 Win32 повинен існувати механізм LoadLibrary в NodeJS?
tgraupmann

78

Зараз є свіжа відповідь на це питання. SWIG , як видається , у версії 3.0 надає генератори інтерфейсів javascript для Node.js, Webkit та v8.

Я деякий час широко використовував SWIG для Java та Python, і як тільки ви зрозумієте, як працює SWIG, майже ніяких зусиль (порівняно з ffi або його еквівалентом на цільовій мові) майже немає, необхідних для взаємодії коду C ++ з мовами SWIG опори.

Як невеликий приклад, скажімо, у вас є бібліотека із заголовком 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;
        }
};

Для того, щоб використовувати цей клас у вузлі, вам просто потрібно написати наступний файл інтерфейсу SWIG (mylib.i):

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

Створіть файл прив'язки.gіp:

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

Виконайте такі команди:

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

Тепер, запустивши вузол з тієї ж папки, ви можете:

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

Незважаючи на те, що нам потрібно було написати два інтерфейсні файли для такого невеликого прикладу, зауважте, як нам не довелося ніде згадувати MyClassконструктор чи sayHelloметод, SWIG виявляє ці речі та автоматично генерує природні інтерфейси.


2
Після невеликої гри з swig / node.js, виявляється, що swig не може обробляти функції C ++, які повертають масиви (точніше: функції, які повертають покажчики на масиви). Тобто, здається, ви не можете побудувати функцію в C ++, яка повертає щось на зразок масиву JavaScript і Swig автоматично перетворить його на вас.
Джордж

5
@George SWIG - це справді дивовижний інструмент, але це не магія, і це не якийсь загальний AI, який може зрозуміти семантику коду С ++ та створити відповідний інтерфейс. Будь ласка, зверніть увагу на те, як семантика C ++ та javascript JavaScript, концепції власності та управління життям принципово відрізняються.
Енобайрам

3
Таким чином, ви можете переглядати SWIG двома способами: це інструмент, який може робити те, що він може робити, і грати за його правилами. Це означає, що ви не повинні сподіватися на те, що з C ++ функцій, які повертають масиви, з'являться масиви javascript. Натомість ви можете зробити, щоб обернути свою функцію в C ++, щоб вона повертала об'єкт, який веде себе як масив ( std::vector<>наприклад, просто %include "std_vector.i"), і ви зможете маніпулювати ним на стороні javascript дещо незграбно. Зауважте, що такий підхід як і раніше набагато простіший і безпечніший, ніж писати самі FFI.
Енобайрам

3
Інший спосіб, яким ви можете користуватися SWIG, - це зрозуміти техніку, що знаходиться під нею. Проведіть кілька місяців, використовуючи його, глибоко вивчіть його особливості. Тоді ви можете змусити його створити інтерфейс, який ви хочете. Ви хочете, щоб він повертав масив javascript для масиву C ++.
Енобайрам

3
У будь-якому випадку, я рекомендую вам почати з першого підходу та вдосконалити використання SWIG на шляху. Досить натхненно вивчити, що SWIG робить до вашого коду і як ви можете ним маніпулювати.
Енобайрам


11

Ви можете використовувати emscripten для компіляції коду C ++ у js.


16
Це було б поганою ідеєю, якщо мета ОП - отримати переваги продуктивності компільованого C ++, а щоб бути педантичним, це не відповідає на питання.
Грег

7
@Greg, але все ж це ідея, яку варто розглянути. На цю сторінку приходять люди для різних проектів. Я думаю, що Emscripten - це хороший варіант, коли у вас є база коду C / C ++ і ви просто хочете використовувати її в Nodejs.
AlexStack

1
- якщо метою ОП є отримання переваг продуктивності компільованого C ++ - Деякі переваги перекладаються на emscripten, особливо з WASM: відсутність накладних витрат на GC, менший синтаксичний аналіз та накладні JIT, натільні числа, оптимізація AOT.
АртемГр

2

Існують новіші способи підключення Node.js і C ++. Будь ласка, награбуйте в Нан .

EDIT Найшвидший і найпростіший спосіб - nbind . Якщо ви хочете написати асинхронну надбудову, ви можете комбінувати Asyncworkerклас з nan.


1

Ось цікава стаття про те, як додати свій C ++ до Інтернету за допомогою Node.js

три загальні способи інтеграції коду C ++ з додатком Node.js, хоча існує велика кількість варіацій у кожній категорії:

  1. Автоматизація - телефонуйте на свій C ++ як окремий додаток у дочірньому процесі.
  2. Спільна бібліотека - упакуйте свої підпрограми C ++ у спільну бібліотеку (dll) та зателефонуйте цим підпрограм з Node.js безпосередньо.
  3. Node.js Addon - компілюйте свій код C ++ як рідний модуль / аддон Node.js.

0

Будьте обережні з swig та C ++: http://www.swig.org/Doc1.3/SWIG.html#SWIG_nn8

Запуск SWIG у вихідних файлах C ++ (що відображатиметься у файлі .C або .cxx) не рекомендується. Навіть незважаючи на те, що SWIG може аналізувати декларації класу C ++, він ігнорує декларації, які відокремлюються від їх початкового визначення класу (декларації аналізуються, але може бути створено багато попереджувальних повідомлень). Наприклад:

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

Рідко є клас C ++, обмежений лише одним .h-файлом.

Також версії swig, що підтримують JavaScript, є swig-3.0.1 або новіші.


Я не розумію, що SWIG би зробив із визначенням у foo::barбудь-якому випадку. Визначення члена класу - все про реалізацію; обгортки, які створюють SWIG, стосуються інтерфейсу.
енобайрам
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.