use libuv function in node.js 0.12.x

青春壹個敷衍的年華 提交于 2019-12-23 20:30:20

问题


I have written a node.js's c++ addon,i can be complied successfully under node.js 0.10.x. But when migrate it to 0.12.x, it failed when several error,such as error C2065: “uv_work_t”:undeclared identifier.I wonder whether i can touch libuv's api in 0.12.x?
The code is showed as follow:

#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() == %d\n",__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() == %d\n",__FUNCTION__,__getThreadId());
    Baton* baton = static_cast<Baton*>(req->data);
    for (int i=0;i<15;i++) {
        __tsleep(1000);
        printf("sleep 1 seconds in uv_work\n");
    }


    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() == %d\n",__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);

I have changed async_hello's paramater,since according to the newest node's API document,it use FunctionCallbackInfo(not Arguments used in node.js 0.10.x) to receive js's paramater.The original code is storage here, and it can be compiled successfully under node.js 0.10.x.


回答1:


just adding #include <uv.h> to the begin of the code can resolve the problem.



来源:https://stackoverflow.com/questions/30141137/use-libuv-function-in-node-js-0-12-x

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!