EDIT: một phương pháp tốt hơn so với một động cơ V8 trần dưới đây là sử dụng NanHasInstance
(https://github.com/rvagg/nan#api_nan_has_instance)
Trong MyObject::Init
:
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(New);
tpl->SetClassName(NanNew<String>("MyObject"));
...
NanAssignPersistent(prototype, tpl);
nơi prototype
là một tĩnh Persistent<FunctionTemplate>
thành viên của MyObject
.
Sử dụng như thế này:
if (NanHasInstance(prototype, handle)) {
MyObject* obj = ObjectWrap::Unwrap<MyObject>(handle);
...
}
Với sự báo trước rằng đây là đi đầu tiên của tôi tại viết một addon Node, tôi giải quyết vấn đề này chính xác bằng cách kiểm tra các nguyên mẫu của đối tượng với wrapper của riêng tôi xung quanh UnWrap
.
Dưới đây là một bản vá để lớp bản demo nhà máy addon cho thấy phương pháp này: https://github.com/petli/node-addon-examples/commit/d3e92cd060a26da2623690718e78f9005db060a8
Nó sẽ chỉ hỗ trợ đối tượng nhà máy tạo ra, chứ không phải những nơi một constructor được tiếp xúc để người dùng có thể kế thừa từ lớp cơ sở. Tuy nhiên, điều đó có thể được khái quát hóa bằng cách đi bộ chuỗi nguyên mẫu.
Nói tóm lại, nó nắm lấy các tham chiếu đến các nguyên mẫu lớp dự kiến trong MyObject::Init
:
Local<Object> obj = constructor->NewInstance();
prototype = Persistent<Value>::New(obj->GetPrototype());
Và sau đó kiểm tra rằng trước khi dereferencing đối tượng:
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;
}
Tất cả các chức năng sau đó sử dụng CheckedUnWrap
thay :
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>();
}
}
Tôi là đồng nghiệp o xem xét thêm một lĩnh vực nội bộ và thiết lập cho một số con trỏ ma thuật, nhưng sau đó mã sẽ phụ thuộc vào đó node::ObjectWrap
sẽ không thay đổi cách nó sử dụng các trường nội bộ.
Cám ơn câu trả lời của bạn được cập nhật. Tôi đang xem lại vấn đề này và hóa ra câu trả lời của bạn "tốt hơn" so với câu trả lời được chấp nhận trước đó. Vì vậy, chấp nhận của bạn – BigONotation