2013-03-13 72 views
4

我正在圍繞C++庫編寫Node.js綁定。我可以識別C++庫中的關鍵對象,我可以將它們公開爲Node.js的類(即ObjectWrap的派生類)。我也可以看到這些對象之間的繼承關係。在node.js綁定中實現繼承

我怎樣才能露出ClassAClassBClassC如Node.js的類(的ObjectWrap衍生物)和操縱其原型(在V8 C++代碼),使得ClassBClassCClassA衍生物?

回答

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 2014-02-03 23:56:56