ฉันจะใช้ไลบรารี 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.