如何在本机C ++ / nodejs插件实现asynchronous构造函数/工厂调用?

我对C ++和node / v8 Addon开发相当陌生。

我试图包装第三方C库。 一些初始化函数运行时间很长,我想运行这些asynchronous操作(在libuv的帮助下)。

鉴于我有以下代码:

#define BUILDING_NODE_EXTENSION #include <node.h> #include "myobject.h" //header files of 3rd party lib to be wrapped #include "3rdparty.h" using namespace v8; MyObject::MyObject(void* base) : baseobject_(base) {}; MyObject::~MyObject() {}; void MyObject::Init(Handle<Object> target) { // Prepare constructor template Local<FunctionTemplate> tpl = FunctionTemplate::New(New); tpl->SetClassName(String::NewSymbol("MyObject")); tpl->InstanceTemplate()->SetInternalFieldCount(1); Persistent<Function> constructor = Persistent<Function>::New(tpl->GetFunction()); target->Set(String::NewSymbol("MyObject"), constructor); } Handle<Value> MyObject::New(const Arguments& args) { HandleScope scope; if (args.IsConstructCall()) { void* cStruct = NULL; // //VERY LONG TAKING OPERATION //Want to run this async with help of libuv createStructIn3rdPartyLib(&cStruct); //create actual Object and pass in cStruct which becomes private field. MyObject* obj = new MyObject(cStruct); obj->Wrap(args.This()); return args.This(); } return scope.Close(Undefined()); } 

我想运行createStructIn3rdPartyLib(&cStruct); 在libuv库的帮助下。

以下是我想出的。 不幸的是,它给了我一个分段错误,我不太确定它是否是正确的方法。 我已经查看了其他本地节点插件的来源,但没有find任何解决scheme,我的问题。 🙁

任何提示欢迎。

 #define BUILDING_NODE_EXTENSION #include <node.h> #include "myobject.h" //header files of 3rd party lib to be wrapped #include "3rdparty.h" using namespace v8; // libuv allows us to pass around a pointer to an arbitrary // object when running asynchronous functions. We create a // data structure to hold the data we need during and after // the async work. typedef struct AsyncData { Persistent<Function> callback; // callback function void *3rdpartydata Arguments *args; } AsyncData; MyObject::MyObject() {}; MyObject::~MyObject() {}; void MyObject::Init(Handle<Object> target) { // Prepare constructor template Local<FunctionTemplate> tpl = FunctionTemplate::New(New); tpl->SetClassName(String::NewSymbol("MyObject")); tpl->InstanceTemplate()->SetInternalFieldCount(1); Persistent<Function> constructor = Persistent<Function>::New(tpl->GetFunction()); target->Set(String::NewSymbol("MyObject"), constructor); target->Set(String::NewSymbol("createObject"), FunctionTemplate::New(New)->GetFunction(CreateObjectAsync)); } Handle<Value> MyObject::New(const Arguments& args) { HandleScope scope; if (args.IsConstructCall()) { void* cStruct = NULL; // //VERY LONG TAKING OPERATION //Want to run this async with help of libuv createStructIn3rdPartyLib(&cStruct); //create actual Object and pass in cStruct which becomes private field. MyObject* obj = new MyObject(&cStruct); obj->Wrap(args.This()); return args.This(); } return scope.Close(Undefined()); } Handle<Value> MyObject::CreateObjectAsync(const Arguments& args) { HandleScope scope; // create an async work token uv_work_t *req = new uv_work_t; // assign our data structure that will be passed around AsyncData *asyncData = new AsyncData(); req->data = asyncData; // expect a function as the 1st argument // we create a Persistent reference to it so // it won't be garbage-collected asyncData->callback = Persistent<Function>::New( Local<Function>::Cast(args[0])); *(asyncData->args) = args; // pass the work token to libuv to be run when a // worker-thread is available to uv_queue_work( uv_default_loop(), req, // work token AsyncWork, // work function (uv_after_work_cb)AsyncAfter // function to run when complete ); return scope.Close(Undefined()); } // Function to execute inside the worker-thread. // It is not safe to access V8, or V8 data structures // here, so everything we need for input and output // should go on our req->data object. void MyObject::AsyncWork(uv_work_t *req) { // fetch our data structure AsyncData *asyncData = (AsyncData *)req->data; // run 3rd Party Function. createStructIn3rdPartyLib(&asyncData->3rdpartydata); } // Function to execute when the async work is complete // this function will be run inside the main event loop // so it is safe to use V8 again void MyObject::AsyncAfter(uv_work_t *req) { HandleScope scope; // fetch our data structure AsyncData *asyncData = (AsyncData *)req->data; // create an arguments array for the callback MyObject *cpBase = new MyObject(asyncData->3rdpartydata); cpBase->Wrap((*asyncData->args).This()); Handle<Value> argv[] = {Null(),(*asyncData->args).This()}; // surround in a try/catch for safety TryCatch try_catch; // execute the callback function asyncData->callback->Call(Context::GetCurrent()->Global(), 2, argv); if (try_catch.HasCaught()) node::FatalException(try_catch); // dispose the Persistent handle so the callback // function can be garbage-collected asyncData->callback.Dispose(); // clean up any memory we allocated delete asyncData; delete req; } 

谢谢!!!

编辑:我读了更多的例子,像节点ogg绑定我越来越认为我在我的方法在错误的轨道上。 也许我应该停留在C / C ++ – Side的一个更低的层面上,并在JavaScript端实现对象function。