Написание модулей ASYNC CPP nodejs (0.5.3+)

Я ищу способ создания С++-модулей для NodeJs с текущей версией (0.5.9). Используя следующий учебник и абстрагирование от узлов node_file.cc, я смог построить модуль самостоятельно для node 0.5.3.

Но с node 0.5.4 некоторые из API'ов должны были измениться, потому что я больше не могу деформировать функции с помощью eio_ *.

Посмотрев на node_file.cc, я обнаружил, что обертка eio_ * заменяется новыми классами ReqWrap.

Пример в этом макросе: https://gist.github.com/1303926

Нет. Интересно, что лучший способ написания расширений async?

Ответ 1

В основном глядя на модуль crypto node, он решил мою проблему, этот модуль не был отлажен макросами, такими как файловый модуль. Я придумал простой асинхронный модуль, который вычисляет сумму двух целых чисел:

#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);

На стороне node вы вызываете модуль следующим образом:

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

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

результат:

undefined 3

Надеюсь, это полезно;)

Ps: Поскольку отсутствие node компиляции расширений под окнами. Я построю это непосредственно в ядре окна node с помощью решения сборки Visual Studio.