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?
Antwort
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.
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.
sieht so aus, als ob es nicht für Versionen funktioniert> Node.js 0.10, hat gerade ein Problem angemeldet, um es sicher herauszufinden –
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
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/
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 ...
- 1. Ist es möglich, "reine" C++ - Klasse in Cython zu schreiben?
- 2. Ist es möglich, ein Betriebssystem komplett in C zu schreiben?
- 3. Ist es möglich, ein selbstzerstörerisches Programm in C zu schreiben?
- 4. Ist es möglich, OpenCL-Kernel in C++ anstatt in C zu schreiben?
- 5. Ist es möglich, C/C++ in Android Studio zu debuggen?
- 6. ist es möglich, ohne stdlibs in die Konsole zu schreiben? c/C++
- 7. Wie ist es möglich, ::: in C++ und ??? in C#?
- 8. Ist es möglich, eine Zeichenkette in C zu ändern?
- 9. Ist es möglich, C++ - Code zu symbolisieren?
- 10. Ist es möglich, eine "Freund-Klasse" in C++ zu erstellen?
- 11. Ist es möglich, eine Präprozessor-Variable in C zu drucken?
- 12. Es ist nicht möglich, eine faktorielle Funktion in C
- 13. Ist es möglich, ein Programm in C zu schreiben, das nichts tut - nicht einmal Speicher belegt?
- 14. Ist es möglich, eine Schleife in Scala Console zu schreiben?
- 15. Ist es möglich, Code zu schreiben, um Code zu schreiben?
- 16. Ist es möglich, eine Firewall in Python zu schreiben?
- 17. Ist es möglich, anonyme Funktionen in C++ .NET zu verwenden?
- 18. Ist es möglich, stderr in C++ zu deaktivieren?
- 19. Ist es möglich, eine interaktive C-Shell zu erstellen?
- 20. Ist es möglich, eine Enum-Deklaration zwischen C# und nicht verwaltetem C++ zu teilen?
- 21. Ist es möglich, temporäre Variablen in C++ explizit zu instanziieren?
- 22. Ist es möglich, Syntax wie -()() zu schreiben?
- 23. Ist es möglich, ActiveX-Steuerelemente in C# zu schreiben, die in Excel ausgeführt werden?
- 24. Ist es möglich, Zeichenfolge und DBNull in C# zu koaleszieren?
- 25. Ist es möglich, mehrere Iteratoren für einen Typ in C# zu schreiben?
- 26. Ist es möglich, Arrays in C# zu erweitern?
- 27. Ist es möglich, eine Variable in C# freizugeben?
- 28. Ist es möglich, eine Jugendschutz-App für iOS zu schreiben?
- 29. Ist es möglich, Operatoren in C zu überladen?
- 30. Ist es möglich, ein generisches Lambda in C# zu definieren?
Ein Link zu Ihrem C++ - Tutorial würde helfen – lupz
https://www.cloudkick.com/blog/2010/aug/23/writing-nodejs-native -extensions/ – noahlz