11 Stimmen

Schreiben von ASYNC CPP nodejs (0.5.3+) Modulen

Ich bin auf der Suche nach einer Möglichkeit, C++ Module für NodeJs mit der aktuellen Version (0.5.9) zu erstellen. Durch die Verwendung des folgenden Tutorials und abstrahieren von Knoten node_file.cc konnte ich ein Modul von meinem Selbst für Knoten 0.5.3 zu bauen.

Aber mit Node 0.5.4 müssen sich einige der APIs geändert haben, da ich nicht mehr in der Lage bin, Funktionen mit eio_* zu warpen.

Bei einem Blick auf node_file.cc habe ich entdeckt, dass das eio_*-Wrapping durch neue ReqWrap-Klassen ersetzt wurde.

Zum Beispiel in diesem Makro: https://gist.github.com/1303926

Nein, ich frage mich, was ist der beste Weg, async-Erweiterungen zu schreiben?

15voto

Alex Punkte 670

Ein Blick auf das Crypto-Node-Modul löste mein Problem, denn dieses Modul war nicht mit Makros überladen wie das Dateimodul. Ich habe mir ein einfaches asynchrones Modul ausgedacht, das die Summe von zwei Ganzzahlen berechnet:

#include <v8.h>
#include <node.h>
#include <stdlib.h>
#include <errno.h>

using namespace node;
using namespace v8;

struct Test_req
{
    ssize_t result;
    ssize_t int1;
    ssize_t int2;
    Persistent<Function> callback;
};

void TestWorker(uv_work_t* req)
{
    Test_req* request = (Test_req*)req->data;
    request->result = request->int1 + request->int2;
}

void TestAfter(uv_work_t* req)
{
    HandleScope scope;

    Test_req* request = (Test_req*)req->data;
    delete req;

    Handle<Value> argv[2];

        // XXX: Error handling
    argv[0] = Undefined();
    argv[1] = Integer::New(request->result);

    TryCatch try_catch;

    request->callback->Call(Context::GetCurrent()->Global(), 2, argv);

    if (try_catch.HasCaught()) 
    {
        FatalException(try_catch);
    }

    request->callback.Dispose();

    delete request;
}

static Handle<Value> Test(const Arguments& args)
{

    HandleScope scope;

    if ( args.Length() < 3 || !args[0]->IsNumber() || !args[1]->IsNumber() )
    {
        return ThrowException(Exception::TypeError(String::New("Bad argument")));
    }

    ssize_t int1 ( args[0]->Int32Value() );
    ssize_t int2 ( args[1]->Int32Value() );

    if ( args[2]->IsFunction() )
    {
        Local<Function> callback = Local<Function>::Cast(args[2]);

        Test_req* request = new Test_req;
        request->callback = Persistent<Function>::New(callback);

        request->int1 = int1;
        request->int2 = int2;

        uv_work_t* req = new uv_work_t();
        req->data = request;

        uv_queue_work(uv_default_loop(), req, TestWorker, TestAfter);
    }
    else
    {
        return ThrowException(Exception::TypeError(String::New("Callback missing")));
    }

    return Undefined();
}

extern "C"
{
    static void init(Handle<Object> target)
    {
        HandleScope scope;
    }
}
NODE_MODULE(node_AsyncTest, init);

Auf der Knotenseite rufen Sie das Modul wie folgt auf:

var foo = process.binding('AsyncTest');

foo.Test(1,2,function(err,data){
  console.log(err,data);
});

Ergebnis:

undefined 3

Ich hoffe, das ist hilfreich ;)

Ps: Da das Fehlen von Node-Kompilier-Erweiterungen unter Windows. Ich baue dies direkt in den Kern des Node-Windows-Port mit der Visual Studio Build-Lösung.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X