2013-03-13 3 views
4

Я пишу привязки Node.js вокруг библиотеки C++. Я могу идентифицировать ключевые объекты в библиотеке C++, которые я могу представить как классы для Node.js (т. Е. Производные ObjectWrap). Я также вижу взаимосвязь между этими объектами.Реализация наследования в привязках node.js

Как я могу выставить ClassA, ClassB, ClassC в node.js классы (производные ObjectWrap) и манипулировать их прототипы (в коде v8 C++), так что ClassB и ClassC являются дериваты ClassA?

ответ

3

Это можно сделать с использованием метода v8::FunctionTemplateInherit. Объясняется here. Вот рабочий пример.

C++ код:

#include <v8.h> 
#include <node.h> 

using namespace node; 
using namespace v8; 

class BaseClass : ObjectWrap 
{ 
public: 
    static Persistent<FunctionTemplate> s_ct; 
    static void Init(v8::Handle<Object> target) 
    { 
    Local<FunctionTemplate> t = FunctionTemplate::New(New); 

    s_ct = Persistent<FunctionTemplate>::New(t); 
    s_ct->InstanceTemplate()->SetInternalFieldCount(1); 
    s_ct->SetClassName(String::NewSymbol("BaseClass")); 

    NODE_SET_PROTOTYPE_METHOD(s_ct, "getName", getName); 

    target->Set(String::NewSymbol("BaseClass"), s_ct->GetFunction()); 
    } 

    BaseClass(){}  
    ~BaseClass(){} 

    static v8::Handle<Value> New(const Arguments& args) 
    { 
    HandleScope scope; 
    return args.This(); 
    } 

    static v8::Handle<Value> getName(const Arguments& args) 
    { 
    HandleScope scope; 
    return scope.Close(String::New("Base")); 
    } 
}; 

Persistent<FunctionTemplate> BaseClass::s_ct; 

class DerivedClass : ObjectWrap 
{ 
public: 
    static Persistent<FunctionTemplate> s_ct; 
    static void Init(v8::Handle<Object> target) 
    { 
    Local<FunctionTemplate> t = FunctionTemplate::New(New); 

    s_ct = Persistent<FunctionTemplate>::New(t); 

    // XXX Inherit from BaseClass 
    s_ct->Inherit(BaseClass::s_ct); 

    s_ct->InstanceTemplate()->SetInternalFieldCount(1); 
    s_ct->SetClassName(String::NewSymbol("DerivedClass")); 

    NODE_SET_PROTOTYPE_METHOD(s_ct, "getAge", getAge); 

    target->Set(String::NewSymbol("DerivedClass"), s_ct->GetFunction()); 
    } 

    DerivedClass() {} 
    ~DerivedClass() {} 

    static v8::Handle<Value> New(const Arguments& args) { 
    HandleScope scope; 
    return args.This(); 
    } 

    static v8::Handle<Value> getAge(const Arguments& args) 
    { 
    HandleScope scope; 
    return scope.Close(Number::New(42)); 
    } 
}; 

Persistent<FunctionTemplate> DerivedClass::s_ct; 

extern "C" { 
    static void init (v8::Handle<Object> target) 
    { 
    BaseClass::Init(target); 
    DerivedClass::Init(target); 
    } 

    NODE_MODULE(mymodule, init); 
} 

Положите его в стандартной конфигурации node-gyp и вы можете проверить его с помощью следующей JavaScript

var mymodule = require('./build/Release/mymodule'); 
var baseObject = new mymodule.BaseClass(); 
var dervObject = new mymodule.DerivedClass(); 

console.log(baseObject.getName()); 
console.log(dervObject.getName(), dervObject.getAge()); 
+0

Это требует FunctionTemplate базового класса. Как бы вы наследовали от v8 :: Array? Я не могу понять, как получить его FunctionTemplate. – user1158559

Смежные вопросы