Node.js'deki bir C ++ kitaplığını nasıl kullanabilirim?


Yanıtlar:


66

Bak düğüm-ffi .

node-ffi, saf JavaScript kullanarak dinamik kitaplıkları yüklemek ve çağırmak için bir Node.js eklentisidir. Herhangi bir C ++ kodu yazmadan yerel kitaplıklara bağlamalar oluşturmak için kullanılabilir.


5
Farklı C ++ derleyicileri farklı ABI'ler oluşturur, bu nedenle node-ffi'yi kullanmak için C ++ kodunuzu bir C arabirimiyle sarmalamanız gerekebilir - veya en azından bunu Windows'ta Visual Studio ile çalıştırmak için yaptım. Bunun nasıl yapılacağına ilişkin ayrıntılar için stackoverflow.com/questions/2045774/… sayfasına bakın . Veya bir sarmalayıcı olmadan C ++ üzerinde node-ffi kullanabilmeli miyim?
— pankek

1
Bu yorumların üzerinden bir yıldan fazla olduğunu biliyorum ama ... C ++ kitaplıklarını C sarıcı olmadan kullanmak mümkün mü?
— Miki de Arcayne

Node-ffi ile VS 2017/2019 derleme sorunlarıyla karşılaştım. Bu büyük bir PITA! Python 2.7'ye mi bağlı yoksa bu sadece inşa süreci mi? Standart bir Win32 DLL için NodeJS'de bir LoadLibrary mekanizması olmalıdır?
— tgraupmann

78

Şimdi bu soruya yeni bir cevap var. SWIG , 3.0 sürümünden itibaren Node.js, Webkit ve v8 için javascript arayüz oluşturucuları sağlıyor gibi görünmektedir .

Bir süredir Java ve Python için kapsamlı olarak SWIG kullanıyorum ve SWIG'nin nasıl çalıştığını anladıktan sonra, C ++ kodunu SWIG'nin kullandığı dillerle arayüzlemek için neredeyse hiç çaba (hedef dildeki ffi veya eşdeğeriyle karşılaştırıldığında) gerekmiyor. destekler.

Küçük bir örnek olarak, myclass.h başlıklı bir kitaplığınız olduğunu varsayalım:

#include<iostream>

class MyClass {
        int myNumber;
public:
        MyClass(int number): myNumber(number){}
        void sayHello() {
                std::cout << "Hello, my number is:" 
                << myNumber <<std::endl;
        }
};

Bu sınıfı düğümde kullanmak için, aşağıdaki SWIG arayüz dosyasını (mylib.i) yazmanız yeterlidir:

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

Bağlama dosyası bağlama.gyp oluşturun:

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

Aşağıdaki komutları çalıştırın:

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

Şimdi, düğümü aynı klasörden çalıştırarak şunları yapabilirsiniz:

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

Bu kadar küçük bir örnek için 2 arayüz dosyası yazmamız gerekmesine rağmen, hiçbir yerde MyClassyapıcıdan veya sayHelloyöntemden bahsetmek zorunda olmadığımıza dikkat edin , SWIG bunları keşfeder ve otomatik olarak doğal arayüzler oluşturur.


2
Bir süre swig / node.js ile oynadıktan sonra, swig'in dizileri döndüren C ++ işlevlerini (daha doğrusu: dizilere işaretçileri döndüren işlevler) işleyemediği anlaşılıyor. Yani, C ++ 'da JavaScript dizisi gibi bir şey döndüren ve swig'in onu sizin için otomatik olarak dönüştürmesini sağlayan bir işlev oluşturamazsınız.
— George

5
@George SWIG gerçekten harika bir araçtır, ancak sihir değildir ve C ++ kodunuzun anlamını anlayabilen ve ilgili bir arayüz oluşturabilen bazı genel yapay zeka değildir. Lütfen C ++ 'ın ve javascript'in semantiğinin, sahiplik kavramlarının ve yaşam boyu yönetiminin temelde ne kadar farklı olduğuna dikkat edin.
— enobayram

3
Böylece SWIG'yi iki şekilde görüntüleyebilirsiniz: Kutudan çıktığı gibi yapabildiğini yapabilen ve kurallarına göre oynayabilen bir araçtır. Bu, javascript dizilerinin dizileri döndüren C ++ işlevlerinden çıkmasını beklememeniz gerektiği anlamına gelir. Bunun yerine yapabileceğiniz şey, işlevinizi bir dizi gibi davranan ( std::vector<>örneğin, sadece %include "std_vector.i") bir nesne döndürmesi için işlevinizi C ++ 'a sarmaktır ve bunu javascript tarafında biraz garip bir şekilde işleyebileceksiniz. Bu yaklaşımın FFI'yı kendiniz yazmaktan çok daha kolay ve güvenli olduğunu unutmayın.
— enobayram

3
SWIG'yi kullanmanın diğer yolu, altındaki makineleri anlamaktır. Kullanarak birkaç ay geçirin, özelliklerini derinlemesine öğrenin. Daha sonra istediğiniz arayüzü oluşturmasını sağlayabilirsiniz. Bir C ++ dizisi için bir javascript dizisi döndürmesini istiyorsunuz, tamam, bunu yapabilirsiniz, ancak önce böyle bir arabirimde beklediğiniz tam anlambilimini nasıl ifade edeceğinizi öğrenmeli ve sorun etki alanınızla iyi eşleştiğinden emin olmalısınız.
— enobayram

3
Her iki durumda da, ilk yaklaşımla başlamanızı ve yolda SWIG kullanımınızı geliştirmenizi tavsiye ederim. SWIG'nin kodunuza ne yaptığını ve onu nasıl değiştirebileceğinizi incelemek oldukça ilham verici.
— enobayram


11

C ++ kodunu js'ye derlemek için emscripten kullanabilirsiniz .


16
OP'nin amacı derlenmiş C ++ performans avantajlarını elde etmekse bu kötü bir fikir olur ve bilgiçlikçi olmak soruyu cevaplamaz.
— Greg

7
@Greg ama yine de dikkate değer bir fikir. İnsanlar elindeki çeşitli proje türleri için bu sayfaya gelir. Bence Emscripten, C / C ++ kod tabanına sahipseniz ve onu Nodejs'de kullanmak istediğinizde iyi bir seçenek.
— AlexStack

1
- OP'nin amacı derlenmiş C ++ 'nın performans avantajlarından yararlanmaksa - Bazı faydalar emscripten ile, özellikle WASM ile çevrilir: GC ek yükü yok, daha az ayrıştırma ve JIT ek yükü, yerel tam sayılar, AOT optimizasyonları.
— ArtemGr

2

Node.js ve C ++ 'ı bağlamanın daha yeni yolları var. En yağma Lütfen Nan .

DÜZENLE En hızlı ve en kolay yol nbind'dir . Eşzamansız eklenti yazmak istiyorsanız, nan'dan Asyncworkersınıfı birleştirebilirsiniz .


1

İşte C ++ 'nızı Node.js ile Web'e Alma hakkında ilginç bir makale

C ++ kodunu bir Node.js uygulamasıyla entegre etmenin üç genel yolu - her kategoride çok sayıda varyasyon olsa da:

  1. Otomasyon - C ++ 'nızı alt süreçte bağımsız bir uygulama olarak arayın.
  2. Paylaşılan kitaplık - C ++ rutinlerinizi paylaşılan bir kitaplıkta (dll) paketleyin ve bu rutinleri doğrudan Node.js'den çağırın.
  3. Node.js Eklentisi - C ++ kodunuzu yerel bir Node.js modülü / eklentisi olarak derleyin.

0

Swig ve C ++ konusunda dikkatli olun: http://www.swig.org/Doc1.3/SWIG.html#SWIG_nn8

SWIG'yi C ++ kaynak dosyalarında (.C veya .cxx dosyasında görünen dosyalar) çalıştırmanız önerilmez. SWIG, C ++ sınıf bildirimlerini ayrıştırabilse de, orijinal sınıf tanımlarından ayrılmış bildirimleri yok sayar (bildirimler çözümlenir, ancak birçok uyarı mesajı üretilebilir). Örneğin:

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

C ++ sınıfının yalnızca bir .h dosyasıyla sınırlı olması nadirdir.

Ayrıca, JavaScript'i destekleyen swig sürümleri swig-3.0.1 veya üstüdür.


foo::barZaten SWIG'nin tanımıyla ne yapacağını anlamıyorum . Bir sınıf üyesinin tanımı tamamen uygulama ile ilgilidir; SWIG'nin oluşturduğu sarmalayıcılar tamamen arayüzle ilgilidir.
— enobayram
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.