C++ V8继承的FunctionTemplate未获取对父FunctionTemplate的更新
我使用V8向应用程序添加JavaScript支持。由于各种原因,我无法深入了解,我们需要能够将方法添加到FunctionTemplate,并使这些方法出现在已经从FunctionTemplate继承的任何FunctionTemplates中 比如说,C++ V8继承的FunctionTemplate未获取对父FunctionTemplate的更新,c++,inheritance,v8,C++,Inheritance,V8,我使用V8向应用程序添加JavaScript支持。由于各种原因,我无法深入了解,我们需要能够将方法添加到FunctionTemplate,并使这些方法出现在已经从FunctionTemplate继承的任何FunctionTemplates中 比如说, v8::Handle<v8::FunctionTemplate> parent; v8::Handle<v8::FunctionTemplate> child; child->Inherit(parent); pare
v8::Handle<v8::FunctionTemplate> parent;
v8::Handle<v8::FunctionTemplate> child;
child->Inherit(parent);
parent->PrototypeTemplate()->Set(isolate, "someNewMethod", v8::FunctionTemplate::New(...));
v8::Handle<v8::FunctionTemplate> base_tmpl;
v8::Handle<v8::Object> base_proto = base_tmpl->GetFunction()->NewInstance();
v8::Handle<v8::FunctionTemplate> derived_tmpl;
v8::Handle<v8::Object> derived_proto = derived_tmpl->GetFunction()->NewInstance();
derived_proto->SetPrototype(base_proto);
base_proto->Set("methodName", v8::FunctionTemplate::New(...)->GetFunction());
然后,secondChild
的实例仍然只有在继承firstChild
时可用的parent
方法
据我所知,V8可能正在积极优化继承关系;从子FunctionTemplate
s实例化的对象不显示原型链,而是将方法直接绑定到它们。因此,我认为我需要使用Object::SetPrototype
来代替它,但我在这方面的每一次尝试都会导致V8崩溃,创建一个原型链,其中继承的方法都不可见,或者具有与FunctionTemplate::Inherit
案例相同的有效行为
在V8中,提供继承方法以将本机方法添加到超类的公认标准机制是什么?一旦实际的
函数
从函数模板
实例化后,对FunctionTemplate
的其他更改不再反映在派生对象中。因此,一旦调用了Inherit
或NewInstance
,就不能更改附加到基础FunctionTemplate
的方法
但是,还有另一种方法可以做到这一点:对于每个本机类,都有一个FunctionTemplate
,然后实例一个代理对象
,直接在原型链中使用。比如说,
v8::Handle<v8::FunctionTemplate> parent;
v8::Handle<v8::FunctionTemplate> child;
child->Inherit(parent);
parent->PrototypeTemplate()->Set(isolate, "someNewMethod", v8::FunctionTemplate::New(...));
v8::Handle<v8::FunctionTemplate> base_tmpl;
v8::Handle<v8::Object> base_proto = base_tmpl->GetFunction()->NewInstance();
v8::Handle<v8::FunctionTemplate> derived_tmpl;
v8::Handle<v8::Object> derived_proto = derived_tmpl->GetFunction()->NewInstance();
derived_proto->SetPrototype(base_proto);
base_proto->Set("methodName", v8::FunctionTemplate::New(...)->GetFunction());
v8::handlebase\u tmpl;
v8::Handle base_proto=base_tmpl->GetFunction()->NewInstance();
v8::句柄派生的\u tmpl;
v8::Handle-derived_-proto=derived_-tmpl->GetFunction()->NewInstance();
派生_proto->SetPrototype(基本_proto);
base_proto->Set(“methodName”,v8::FunctionTemplate::New(…)->GetFunction());
然后,当您要实例化对象时,可以执行以下操作:
v8::Handle<v8::ObjectTemplate> instance_tmpl;
instance_tmpl->SetInternalFieldCount(1);
v8::Handle<v8::Object> instance = instance_tmpl->NewInstance();
instance->SetInternalField(0, nativeObject);
instance->SetPrototype(derived_proto);
v8::Handle实例\u tmpl;
实例\u tmpl->SetInternalFieldCount(1);
v8::Handle instance=instance_tmpl->NewInstance();
实例->设置内部字段(0,nativeObject);
实例->设置原型(派生的原型);
从技术上讲,您只需实例化代理
对象
s,但仍然具有函数模板
,允许您使用其SetClassName
(用于调试)以及对象::FindInstanceInPrototypeChain
(用于运行时类型检查等).我的经验似乎与你的不同。我确实可以在原型上设置方法,并且可以通过继承来使用它们,即使在调用子对象上的FunctionTemplate::Inherit
后添加了这些方法
我工作测试的全部来源只是总结
我像这样创建了parent
类
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
t->SetClassName(v8::String::NewFromUtf8(isolate, "A_Parent"));
auto proto = t->PrototypeTemplate();
proto->Set(v8::String::NewFromUtf8(isolate, "methodA"), v8::FunctionTemplate::New(isolate, MethodACallback));
(您会注意到,我在子继承父继承后添加了方法b
)
然后我将A_Child
函数导入到全局上下文中
ctx->Global()->Set(v8::String::NewFromUtf8(isolate, "A_Child"), child->GetFunction());
…并编译/运行以下脚本
"use strict";
var c = new A_Child();
c.methodA();
c.methodB();
哪个输出
methodA called from [object A_Child]
methodB called from [object A_Child]
我使用的是v8 4.2.0,并使用Clang3.3进行编译。在OS X 10.8.5上运行的v8文档非常糟糕。您是否尝试过查看v8.h
中的注释?它们可以提供相当多的信息。@gmbeard我已经仔细地梳理了它们,关于FunctionTemplate和继承的评论只会让事情变得更加混乱。。。我只是希望这是其他人遇到的问题,并且知道应该有明显的解决方法。文档中说,从secondChild->GetFunction()->NewInstance()
返回的Object
实例应该有newMethod
。不是这样吗?@gmbeard问题是我需要从ObjectTemplate
中执行实例,这样我就可以首先设置内部字段计数(因为它是由本机对象支持的),而我看不到使用GetFunction()
执行此操作的任何方法-因此我一直在调用NewInstance()
在函数模板::InstanceTemplate()
上。我很确定您可以执行secondChild->InstanceTemplate()->SetInternalFieldCount(1)
然后调用secondChild->GetFunction()->NewInstance()。不过,在您实际实例化对象的方式和我的方式之间有几个显著的差异;例如,我的对象都在本机端实例化,我正在实例化InstanceTemplate
,因为在实例化函数模板时无法添加内部数据(根据我们在聊天中的讨论)。但这不会有什么不同。。。