2012-05-06 13 views
17

Eine schnelle Google-Suche ergibt mindestens ein Tutorial zum Schreiben eines C++ "Hello World" für node.js, aber es ist unklar, ob es möglich ist, eine solche Erweiterung nur mit C zu schreiben. Angenommen, es ist möglich, welchen Herausforderungen/Einschränkungen würde ich gegenüberstehen?Ist es möglich, eine Node.js-Erweiterung in C (nicht C++) zu schreiben?

+2

Ein Link zu Ihrem C++ - Tutorial würde helfen – lupz

+0

https://www.cloudkick.com/blog/2010/aug/23/writing-nodejs-native -extensions/ – noahlz

Antwort

15

Sie können Teile Ihrer Erweiterung in C schreiben, wenn Sie möchten, aber Sie benötigen mindestens ein wenig C++ - Code, um Ihren C-Code mit Node zusammenzufügen.

Wie Sie in Ihrem HelloWorld gesehen haben, stützen sich Erweiterungen auf die Header v8.h und node.h, die alle Klassen enthalten, die Node erwartet. Ohne diese können Sie das JS-Objekt, das zurück zum Knoten exportiert werden soll, nicht ordnungsgemäß erstellen.

Das heißt, Sie können ziemlich einfach nur eine kleine Gruppe von C++ - Funktionen schreiben, die nur C-Funktionen aufrufen und eine Art C-Struktur umhüllen.

2

Der Code, der direkt mit node.js interagiert, muss in C++ geschrieben sein.

Sie konnte schreiben extern "C" Wrapper undurchsichtige Typen für alles verwenden, müssen von node.h und v8.h, aber es ist wahrscheinlich einfacher zu benutzen C++ nur statt (was natürlich kann in C-Code rufen).

8

Fand dieses auf Hacker News:

https://github.com/wesolows/v8plus

v8 +: Node Addon C++ zu C Grenze

Diese Schicht bietet eine Möglichkeit, zumindest einfache Knoten Addons in C ohne alle zu schreiben Schreckliches C++, was man sonst erwarten würde. Dieser Goop existiert noch, aber Sie müssen ihn nicht schreiben. Noch wichtiger ist, dass Sie Ihr Modul in einer vernünftigen Programmierumgebung schreiben können, um die verwirrende und fehleranfällige C++ - Semantik zu vermeiden.

+0

sieht so aus, als ob es nicht für Versionen funktioniert> Node.js 0.10, hat gerade ein Problem angemeldet, um es sicher herauszufinden –

5

Notwendigkeit, die einzelne C-Funktion in C++ Code mit der extern "C" Syntax

Beispiel zu erklären:

#define BUILDING_NODE_EXTENSION 
#include <node.h> 

extern "C" void f(int i, char c, float x); 

using namespace v8; 

, wenn Sie mehr C-Funktionen haben, dann kann es über gruppiert werden Streben:

extern "C" { 
    void f(int i, char c, float x); 
    int g(char* s, char const* s2); 
    double sqrtOfSumOfSquares(double a, double b); 
} 

dann die Funktion aus dem C++ Funktionsaufruf:

Handle<Value> MyFunction(const Arguments& args) { 
    HandleScope scope; 
    f(7, 'x', 3.14); // <--- 
    return scope.Close(String::New("Hello")); 
} 

Handle<Value> CreateFunction(const Arguments& args) { 
    HandleScope scope; 

    Local<FunctionTemplate> tpl = FunctionTemplate::New(MyFunction); 
    Local<Function> fn = tpl->GetFunction(); 
    fn->SetName(String::NewSymbol("theFunction")); // omit this to make it anonymous 

    return scope.Close(fn); 
} 

void Init(Handle<Object> target) { 
    target->Set(String::NewSymbol("createFunction"), 
     FunctionTemplate::New(CreateFunction)->GetFunction()); 
} 


NODE_MODULE(addon, Init) 

Hinweis: Die Verwendung von Beispielcode Nodejs Addons

5

Jetzt haben wir mindestens drei gute Möglichkeiten:

Knoten-ffi: Node.js Foreign Function Interface
Add-on für das Laden und ruft dynamische Bibliotheken, die reines JavaScript verwenden.Es kann Bindungen an nativen Bibliotheken verwendet werden, zu erstellen, ohne einen C-Code schreiben
https://github.com/node-ffi/node-ffi

SWIG: Simplified Wrapper and Interface Generator
(es Wrapper für viele Sprachen erzeugt, was auf einmal viele Probleme löst)
http://www.swig.org/

Emscripten
Kompiliert C und C++ in hoch optimierbar JavaScript, das bei nahezu nativer Geschwindigkeit sogar auf das Netz läuft, ohne Plugins.
http://kripken.github.io/emscripten-site/

0

Wenn Ihr Modul libuv verwendet, können Sie es mit dem ausführbaren Knoten verbinden. Es exportiert die libuv-Funktionen wie eine gemeinsam genutzte Bibliothek.

Dann können Sie node-ffi verwenden, um damit zu interagieren (hier ist kein C++ - Wissen erforderlich).

Hier ist, wie ich es unter Windows gemacht, mit MSVS:

  • eine neue DLL-Lösung in MSVS erstellen
  • die libuv Herunterladen und die umfassen und die lib-Dateien in das MSVS
  • kopieren Download die node.lib Datei und es in den Ordner lib MSVS setzen
  • das Beispiel Quelle Kompilieren unter dem einen Timer auf die Hauptereignisschleife fügt

testlib.c:

#include <stdio.h> 
#include <stdlib.h> 
#include "uv.h" 

void (*p_callback)(int number, char *text); 

void timer_cb1 (uv_timer_t* timer, int status) { 
    printf("libuv timer here\n", status); 
    p_callback(123, "it worked!"); 
} 

void set_timer (int interval, void *pfunction) { 
    uv_loop_t *loop; 
    uv_timer_t *timer1; 

    printf("set_timer called. interval=%d callback=%p\n", interval, pfunction); 

    p_callback = pfunction; 

    printf("uv_version_string = %s\n", uv_version_string()); 

    loop = uv_default_loop(); 
    if (loop == 0) { 
    puts("could not get the reference to the default loop"); 
    return; 
    } 

    puts("got the default loop. now allocating the timer struct"); 

    timer1 = (uv_timer_t *) malloc(sizeof(uv_timer_t)); 
    if (timer1 == 0) { 
    puts("malloc failed"); 
    return; 
    } 

    puts("initializing timer"); 
    uv_timer_init(loop, timer1); 

    puts("starting timer"); 
    uv_timer_start(timer1, (uv_timer_cb) &timer_cb1, interval, interval); 

    puts("timer created. returning"); 

} 

die testlib.def verwenden:

EXPORTS set_timer 

Und denken Sie daran, die node.lib

  • Bewegen Sie die erstellte DLL auf den Testordner zu verknüpfen und führen Sie diese Befehle dort aus:

npm install ffi (derzeit sind die Build-Tools erforderlich. Überprüfen Sie die Anweisungen)

node test-lib.js

Test-lib.js ist hier:

var ffi = require('ffi'); 

var testlib = ffi.Library('testlib', { 
    'set_timer': [ 'void', [ 'int', 'pointer' ] ] 
}); 

var callback = ffi.Callback('void', ['int', 'string'], 
    function(number, text) { 
    console.log("javascript callback here!!! number=" + number + " text=" + text); 
    } 
); 

console.log('registering the callback...'); 
testlib.set_timer(500, callback); 
console.log('done') 

Verwenden Sie Ihre Phantasie. Wir haben Vernetzung, Worker-Threads und andere Optionen innerhalb libuv ...

Verwandte Themen