在node.js 0.12.x中使用libuv函数

use libuv function in node.js 0.12.x

本文关键字:libuv 函数 node js      更新时间:2023-10-16

我已经写了一个node.js的C 插件,可以在Node.js 0.10.x中成功遵守我。但是,当将其迁移到0.12.x时,当几个错误(例如error C2065: “uv_work_t”:undeclared identifier)时,它失败了。我想知道我是否可以在0.12.x中触摸Libuv的API?
该代码显示如下:

#include <node.h>
#include <string>
#include <v8.h>
#ifdef WINDOWS_SPECIFIC_DEFINE
#include <windows.h>
typedef DWORD ThreadId;
#else
#include <unistd.h>
#include <pthread.h>
typedef unsigned int ThreadId;
#endif
using namespace v8;
void async_hello(const FunctionCallbackInfo<Value>& args);
//not in main thread,called in uv thread pool
void call_work(uv_work_t* req);
//the callback function
void call_work_after(uv_work_t* req);
static ThreadId __getThreadId() {
    ThreadId nThreadID;
#ifdef WINDOWS_SPECIFIC_DEFINE
    nThreadID = GetCurrentProcessId();
    nThreadID = (nThreadID << 16) + GetCurrentThreadId();
#else
    nThreadID = getpid();
    nThreadID = (nThreadID << 16) + pthread_self();
#endif
    return nThreadID;
}
static void __tsleep(unsigned int millisecond) {
#ifdef WINDOWS_SPECIFIC_DEFINE
    ::Sleep(millisecond);
#else
    usleep(millisecond*1000);
#endif
}
//defined a struct to storage the async reqution information
struct Baton {
    //must be declared as the type of Persistent,when callback finished successfully,execute the function dispose to release.
    Persistent<Function> callback;
    // 
    bool error;
    std::string error_message;
    //save the string passed from js
    std::string input_string;
    //save the string return to js
    std::string result;
};

void async_hello(const Arguments& args) {
    printf("n%s Thread id : gettid() == %dn",__FUNCTION__,__getThreadId());
    Isolate* isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);
    if(args.Length() < 2) { 
        ThrowException(Exception::TypeError(String::New("Wrong number of arguments"))); 
        return; 
      } 

    if (!args[0]->IsString() || !args[1]->IsFunction()) {
        ThrowException(Exception::TypeError(
            String::New("Wrong number of arguments")));
        return;
    }

    Local<Function> callback = Local<Function>::Cast(args[1]);
    Baton* baton = new Baton();
    baton->error = false;
    baton->callback = Persistent<Function>::New(callback);
    v8::String::Utf8Value param1(args[0]->ToString());
    baton->input_string = std::string(*param1); 
    uv_work_t *req = new uv_work_t();
    req->data = baton;
    int status = uv_queue_work(uv_default_loop(), req, call_work,
                               (uv_after_work_cb)call_work_after);
    assert(status == 0);
    return 
}
//not in main thread
void call_work(uv_work_t* req) {
    printf("n%s Thread id : gettid() == %dn",__FUNCTION__,__getThreadId());
    Baton* baton = static_cast<Baton*>(req->data);
    for (int i=0;i<15;i++) {
        __tsleep(1000);
        printf("sleep 1 seconds in uv_workn");
    }

    baton->result = baton->input_string+ "--->hello world from c++";
}

//return to main thread
void call_work_after(uv_work_t* req) {
    printf("n%s Thread id : gettid() == %dn",__FUNCTION__,__getThreadId());    
    Isolate* isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);
    Baton* baton = static_cast<Baton*>(req->data);
    if (baton->error) {
        Local<Value> err = Exception::Error(String::New(baton->error_message.c_str()));
        //
        const unsigned argc = 1;
        Local<Value> argv[argc] = { err };
        //
        TryCatch try_catch;
        baton->callback->Call(Context::GetCurrent()->Global(), argc, argv);
        if (try_catch.HasCaught()) {
            node::FatalException(try_catch);
        }
    } else {
        const unsigned argc = 2;
        Local<Value> argv[argc] = {
            Local<Value>::New(Null()),
            Local<Value>::New(String::New(baton->result.c_str()))
        };
        TryCatch try_catch;
        baton->callback->Call(Context::GetCurrent()->Global(), argc, argv);
        if (try_catch.HasCaught()) {
            node::FatalException(try_catch);
        }
    }
    //relase Persistent callback
    baton->callback.Dispose();
    // release the memory space
    delete baton;
    delete req;
}
void RegisterModule(Handle<Object> target) {
    target->Set(String::NewSymbol("async_hello"),FunctionTemplate::New(async_hello)->GetFunction());
}
NODE_MODULE(binding, RegisterModule);

我更改了async_hello的Paramater,因为根据最新的节点的API文档,它使用FunctionCallbackInfo(不是Node.js 0.10.x中使用的Arguments)接收JS的Paramater。原始代码在这里存储,并且可以在Node.js 0.10.x。

下成功编译

只是将#include <uv.h>添加到代码的开头可以解决问题。