我有2个C++类作为javascript类公开,VanillaOption并且NoomraEngine都继承自ObjectWrap.
在下面的方法中NoomraEngine,我应该收到一个以前的"包装" VanillaOption:
Handle<Value>
NoomraEngine::Price(const Arguments& args) {
HandleScope scope;
Local<Object> object = args[0]->ToObject(); // VanillaOption expected in args[0]
VanillaOption* equityOption = ObjectWrap::Unwrap<VanillaOption>(object);
Local<Number> x = Number::New(this->price(equityOption));
return scope.Close(x);
}
Run Code Online (Sandbox Code Playgroud)
一切正常,但如果我将错误的类型传递给方法,节点崩溃了ObjectWrap::Unwrap.
我的问题是如何确保我收到了正确的类型args[0]?
编辑:比下面的裸 V8 更好的方法是使用NanHasInstance(https://github.com/rvagg/nan#api_nan_has_instance)
在MyObject::Init:
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(New);
tpl->SetClassName(NanNew<String>("MyObject"));
...
NanAssignPersistent(prototype, tpl);
Run Code Online (Sandbox Code Playgroud)
其中prototype是 的静态Persistent<FunctionTemplate>成员MyObject。
像这样使用:
if (NanHasInstance(prototype, handle)) {
MyObject* obj = ObjectWrap::Unwrap<MyObject>(handle);
...
}
Run Code Online (Sandbox Code Playgroud)
需要注意的是,这是我第一次编写 Node 插件,我通过使用我自己的包装器检查对象的原型解决了这个问题UnWrap。
这是插件工厂类演示的补丁,显示了该方法: https://github.com/petli/node-addon-examples/commit/d3e92cd060a26da2623690718e78f9005db060a8
它仅支持工厂生成的对象,而不支持公开构造函数以便用户可以从基类继承的对象。然而,这可以通过遍历原型链来推广。
总之,它抓住了对预期类原型的引用MyObject::Init:
Local<Object> obj = constructor->NewInstance();
prototype = Persistent<Value>::New(obj->GetPrototype());
Run Code Online (Sandbox Code Playgroud)
然后在取消引用对象之前检查:
MyObject* MyObject::CheckedUnWrap(Handle<Object> handle)
{
if (!handle.IsEmpty() && handle->InternalFieldCount() == 1) {
Handle<Value> objproto = handle->GetPrototype();
if (objproto == prototype) {
// OK, this is us
return ObjectWrap::Unwrap<MyObject>(handle);
}
}
ThrowException(Exception::TypeError(String::New("<this> is not a MyObject")));
return NULL;
}
Run Code Online (Sandbox Code Playgroud)
然后所有函数都使用CheckedUnWrap:
Handle<Value> MyObject::PlusOne(const Arguments& args) {
HandleScope scope;
MyObject* obj = CheckedUnWrap(args.This());
if (obj) {
obj->counter_ += 1;
return scope.Close(Number::New(obj->counter_));
}
else {
// Invalid type, an exception has been thrown so return an empty value
return Handle<Value>();
}
}
Run Code Online (Sandbox Code Playgroud)
我还考虑添加一个内部字段并将其设置为一些魔术指针,但是代码将依赖于它不会node::ObjectWrap改变它使用内部字段的方式。
| 归档时间: |
|
| 查看次数: |
1910 次 |
| 最近记录: |