Nan无法用v8 :: Object字段打包和解包对象

起初,我是这样定义的(基本上和文档中的对象包装例子一样,唯一的区别是这个例子包装了一个double值属性,但是我的是一个v8::Object ):

。H:

 #include <nan.h> using v8::Local; using v8::Object; using Nan::FunctionCallbackInfo; class MyObject : public Nan::ObjectWrap { public: static void Init(v8::Local<v8::Object> module); private: explicit MyObject(Local<Object>); ~MyObject(); static Nan::Persistent<v8::Function> constructor; static void New(const FunctionCallbackInfo<v8::Value>& info); static void GetConfig(const FunctionCallbackInfo<v8::Value>& info); Local<Object> Config; }; 

.CC:

 using v8::Local; using v8::Object; Nan::Persistent<v8::Function> MyObject::constructor; MyObject::MyObject(Local<Object> config) : Config(config){} MyObject::~MyObject(){} // return an object when required void MyObject::Init(Local<Object> module) { Nan::HandleScope scope; Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New); tpl->SetClassName(Nan::New("myObject").ToLocalChecked()); tpl->InstanceTemplate()->SetInternalFieldCount(1); // prototypes Nan::SetPrototypeMethod(tpl, "getConfig", GetConfig); constructor.Reset(tpl->GetFunction()); module->Set(Nan::New("exports").ToLocalChecked(), tpl->GetFunction()); } void MyObject::New(const Nan::FunctionCallbackInfo<v8::Value>& info) { Local<Object> conf = info[0].As<Object>(); MyObject* myObject = new MyObject(conf); MyObject->Wrap(info.This()); info.GetReturnValue().Set(info.This()); } void MyObject::GetConfig(const Nan::FunctionCallbackInfo<v8::Value>& info) { MyObject* myObject = ObjectWrap::Unwrap<MyObject>(info.Holder()); Local<Object> conf = myObject->Config; info.GetReturnValue().Set(conf); } 

JS:

 var Test = require("./build/Release/test"); var test = new Test({a: 1}); console.log(test.getConfig()); // logs 3276x randomly 

似乎Config领域得到垃圾收集。 如果是这样的情况,我不明白为什么,因为MyObject实例显然还在范围之内。 但是我仍然试图让Config持久。

有趣的是,直接将Config的types改变为Persistent<Object> *也不起作用,但是当我添加这些似乎无关的行来testing是否在对象被包装在MyObject::New()之前从js传递了正确的对象时, , 有效:

 Local<Object> test = Nan::New(*MyObject->Config); Local<v8::String> v8Str = Nan::To<v8::String> (test->Get(Nan::New("a").ToLocalChecked())).ToLocalChecked(); v8::String::Utf8Value v8StrUtf8(v8Str); std::string str = std::string(*v8StrUtf8); std::cout << str << std::endl; 

这里有什么问题? 什么是正确的方式来包装一个V8 ::对象? 为什么这些财产访问线路可以使其工作?

如果你想要保持更长时间的值(超出当前范围),则需要将引用设置为“持久”而不是“本地”。 这样做会阻止垃圾收集的价值。

因此,将您的Config定义更改为:

 Nan::Persistent<Object> Config; 

我没有testing过,但是你可能还需要把你的构造函数改为:

 MyObject::MyObject(Local<Object> config) { Config.Reset(config); } 

然后,当你想要检索你需要的值时,可以从Persistent中获得一个Local句柄,如:

 Local<Object> conf = Nan::New(myObject->Config);