ฉันจะใช้ไลบรารี C ++ จาก node.js ได้อย่างไร


130

ฉันจะใช้ไลบรารี C ++ จาก node.js ได้อย่างไร


9
คำสำคัญคือextension. ส่วนขยาย
— Peter Wood

5
ตามลิงค์นี้. ได้จัดเตรียมโปรแกรมตัวอย่างและอธิบายทีละขั้นตอน benfarrell.com/2013/01/03/…

คำตอบ:


66

ดูโหนด FFI

node-ffi เป็นส่วนเสริม Node.js สำหรับการโหลดและเรียกไลบรารีไดนามิกโดยใช้ JavaScript บริสุทธิ์ สามารถใช้เพื่อสร้างการเชื่อมโยงกับไลบรารีดั้งเดิมโดยไม่ต้องเขียนโค้ด C ++ ใด ๆ


5
คอมไพเลอร์ C ++ ที่แตกต่างกันสร้าง ABI ที่แตกต่างกันดังนั้นในการใช้ node-ffi คุณอาจต้องรวมโค้ด C ++ ของคุณด้วยอินเทอร์เฟซ C หรืออย่างน้อยฉันก็ทำเพื่อให้สิ่งนี้ทำงานบน Windows ด้วย Visual Studio โปรดดูstackoverflow.com/questions/2045774/…สำหรับรายละเอียดวิธีการดำเนินการนี้ หรือฉันควรจะใช้ node-ffi บน C ++ โดยไม่ต้องใช้ wrapper ได้
— pancake

1
ฉันรู้ว่ามันเป็นเวลามากกว่าหนึ่งปีแล้วที่ความคิดเห็นนี้ แต่ ... เป็นไปได้ไหมที่จะใช้ C ++ libs โดยไม่มี C wrapper?
— Miki de Arcayne

ฉันพบปัญหาการคอมไพล์ VS 2017/2019 กับ node-ffi เป็น PITA ที่สำคัญ! มันขึ้นอยู่กับ Python 2.7 หรือเป็นเพียงกระบวนการสร้าง? ต้องมีกลไก LoadLibrary ใน NodeJS สำหรับ Win32 DLL มาตรฐาน?
— 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"

สร้างไฟล์ที่มีผลผูกพัน binding.gyp:

{
  "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

แม้ว่าเราจะต้องเขียนไฟล์อินเทอร์เฟซ 2 ไฟล์สำหรับตัวอย่างเล็ก ๆ เช่นนี้โปรดสังเกตว่าเราไม่ต้องพูดถึงตัวMyClassสร้างหรือsayHelloวิธีการใดก็ตาม SWIG ค้นพบสิ่งเหล่านี้และสร้างอินเตอร์เฟสที่เป็นธรรมชาติโดยอัตโนมัติ


2
หลังจากเล่นกับ swig / node.js สักครู่ดูเหมือนว่า swig ไม่สามารถจัดการกับฟังก์ชัน C ++ ที่ส่งคืนอาร์เรย์ได้ (แม่นยำยิ่งขึ้น: ฟังก์ชันที่ส่งคืนตัวชี้ไปยังอาร์เรย์) นั่นคือดูเหมือนว่าคุณไม่สามารถสร้างฟังก์ชั่นใน C ++ ที่ส่งคืนบางอย่างเช่นอาร์เรย์ JavaScript และ swig จะแปลงให้คุณโดยอัตโนมัติ
— George

5
@George SWIG เป็นเครื่องมือที่น่าทึ่งจริง ๆ แต่มันไม่ใช่เวทมนตร์และไม่ใช่ AI ทั่วไปที่สามารถเข้าใจความหมายของโค้ด C ++ ของคุณและสร้างอินเทอร์เฟซที่เกี่ยวข้องได้ โปรดสังเกตว่าความหมายของ C ++ และจาวาสคริปต์แนวคิดความเป็นเจ้าของและการจัดการอายุการใช้งานแตกต่างกันอย่างไร
— enobayram

3
คุณจึงสามารถดู SWIG ได้สองวิธี: เป็นเครื่องมือที่สามารถทำสิ่งที่ทำได้นอกกรอบและเล่นตามกฎของมัน นั่นหมายความว่าคุณไม่ควรคาดหวังว่าจะเห็นอาร์เรย์จาวาสคริปต์ปรากฏขึ้นจากฟังก์ชัน C ++ ที่ส่งคืนอาร์เรย์ สิ่งที่คุณทำได้คือห่อฟังก์ชันของคุณใน C ++ เพื่อให้ส่งคืนวัตถุที่ทำหน้าที่เหมือนอาร์เรย์ ( std::vector<>เช่น just %include "std_vector.i") และคุณจะสามารถจัดการกับด้านจาวาสคริปต์ในลักษณะที่ค่อนข้างอึดอัด โปรดทราบว่าแนวทางนี้ยังง่ายกว่าและปลอดภัยกว่าการเขียน FFI ด้วยตัวเอง
— enobayram

3
อีกวิธีหนึ่งที่คุณสามารถใช้ SWIG คือการเข้าใจเครื่องจักรที่อยู่ข้างใต้ ใช้เวลาสองสามเดือนในการใช้งานเรียนรู้คุณสมบัติเชิงลึก จากนั้นคุณสามารถสร้างอินเทอร์เฟซที่คุณต้องการได้ คุณต้องการให้ส่งคืนอาร์เรย์จาวาสคริปต์สำหรับอาร์เรย์ C ++ ได้ดีคุณสามารถทำได้ แต่ก่อนอื่นคุณควรเรียนรู้วิธีแสดงความหมายตามที่คุณคาดหวังในอินเทอร์เฟซดังกล่าวและตรวจสอบให้แน่ใจว่าแมปกับโดเมนปัญหาของคุณ
— enobayram

3
ไม่ว่าจะด้วยวิธีใดฉันขอแนะนำให้คุณเริ่มต้นด้วยแนวทางแรกและปรับแต่งการใช้ SWIG ระหว่างทาง เป็นแรงบันดาลใจในการศึกษาว่า SWIG ทำอะไรกับโค้ดของคุณและคุณจะจัดการกับมันได้อย่างไร
— enobayram


11

คุณสามารถใช้emscriptenเพื่อรวบรวมรหัส C ++ เป็น js


16
นี่จะเป็นความคิดที่ไม่ดีถ้าเป้าหมายของ OP คือการได้รับประโยชน์ด้านประสิทธิภาพของ C ++ ที่คอมไพล์และการอวดดีมันไม่ได้ตอบคำถาม
— Greg

7
@Greg แต่ก็ยังเป็นความคิดที่ควรค่าแก่การพิจารณา ผู้คนมาที่หน้านี้เพื่อดูโครงการประเภทต่างๆในมือ ฉันคิดว่า Emscripten เป็นตัวเลือกที่ดีเมื่อคุณมีฐานรหัส C / C ++ และต้องการใช้ใน Nodejs
— AlexStack

1
- หากเป้าหมายของ OP คือการได้รับประโยชน์ด้านประสิทธิภาพของ C ++ ที่คอมไพล์ - ประโยชน์บางประการแปลด้วย emscripten โดยเฉพาะกับ WASM: ไม่มีค่าใช้จ่าย GC การแยกวิเคราะห์น้อยลงและค่าโสหุ้ย JIT จำนวนเต็มเนทีฟการเพิ่มประสิทธิภาพ AOT
— ArtemGr

2

มีวิธีใหม่กว่าในการเชื่อมต่อ Node.js และ C ++ กรุณายกเค้าที่น่าน

แก้ไข วิธีที่เร็วและง่ายที่สุดคือnbind หากคุณต้องการเขียนโปรแกรมเสริมแบบอะซิงโครนัสคุณสามารถรวมAsyncworkerคลาสจาก nan


1

นี่คือบทความที่น่าสนใจเกี่ยวกับการนำ C ++ ของคุณเข้าสู่เว็บด้วย Node.js

สามวิธีทั่วไปในการรวมโค้ด C ++ กับแอปพลิเคชัน Node.js แม้ว่าจะมีรูปแบบต่างๆมากมายในแต่ละหมวดหมู่:

  1. ระบบอัตโนมัติ - เรียก C ++ ของคุณเป็นแอปแบบสแตนด์อโลนในกระบวนการย่อย
  2. ไลบรารีที่ใช้ร่วมกัน - แพ็ครูทีน C ++ ของคุณในไลบรารีที่ใช้ร่วมกัน (dll) และเรียกรูทีนเหล่านั้นจาก Node.js โดยตรง
  3. Node.js Addon - คอมไพล์โค้ด C ++ ของคุณเป็นโมดูล Node.js ดั้งเดิม / addon

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ต่อไป คำจำกัดความของสมาชิกชั้นเรียนเป็นข้อมูลเกี่ยวกับการนำไปใช้งาน Wrapper ที่ SWIG สร้างขึ้นล้วนเกี่ยวกับอินเทอร์เฟซ
— enobayram
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.