EDIT: un metodo migliore di nudo V8 quella qui sotto è usare NanHasInstance
(https://github.com/rvagg/nan#api_nan_has_instance)
In MyObject::Init
:
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(New);
tpl->SetClassName(NanNew<String>("MyObject"));
...
NanAssignPersistent(prototype, tpl);
dove prototype
è un statico Persistent<FunctionTemplate>
membro di MyObject
.
Usa come questo:
if (NanHasInstance(prototype, handle)) {
MyObject* obj = ObjectWrap::Unwrap<MyObject>(handle);
...
}
Con l'avvertenza che questo è il mio primo tentativo di scrivere un addon Nodo, ho risolto questo problema esatto controllando il prototipo dell'oggetto con il mio wrapper UnWrap
.
Ecco una patch per la classe addon fabbrica demo che mostra il metodo: https://github.com/petli/node-addon-examples/commit/d3e92cd060a26da2623690718e78f9005db060a8
Sosterrà solo gli oggetti in fabbrica generato, e non quelle in cui un costruttore è esposto in modo che gli utenti potevano ereditare dalla classe base. Tuttavia, ciò potrebbe essere generalizzato camminando sulla catena del prototipo.
In sintesi, si afferra il riferimento al prototipo di classe previsto MyObject::Init
:
Local<Object> obj = constructor->NewInstance();
prototype = Persistent<Value>::New(obj->GetPrototype());
E poi controlla che prima dereferencing l'oggetto:
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;
}
Tutte le funzioni quindi utilizzare CheckedUnWrap
invece :
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>();
}
}
I was als o considerando di aggiungere un campo interno e impostarlo su qualche puntatore magico, ma il codice sarebbe dipeso dal fatto che lo node::ObjectWrap
non cambierebbe il modo in cui utilizza i campi interni.
Grazie per la risposta aggiornata. Sto rivisitando questo problema e risulta che la tua risposta è "migliore" della risposta precedentemente accettata. Quindi accettando il tuo – BigONotation