我想在v8中公开C ++类成员,我知道如何公开类方法,但我不知道如何公开类成员。
C ++类:
class Person{
public:
string name;
}
使用Javascript:
var p1 = new Person();
p1.name = "Jack";
我想实现这一目标,这是可能的。谢谢!
答案 0 :(得分:3)
您可以将SetAccessor()
用于Person原型模板,将该成员的指针作为外部V8数据提供。但是你需要将Person的C ++实例包装到V8对象中,然后将这个V8对象从他们的args中解压缩到访问者getter / setter回调中的C ++对象。这个()
我在v8pp
库中使用这种方式。该库简化了C ++类和函数到V8的展示。对于类成员变量,它看起来像这样:
v8pp::class_<Person> Person_class(isolate);
Person_class
// bind member variable
.set("name", &Person::name)
答案 1 :(得分:0)
pmed说的是正确的,但是为了扩展一点,你可以使用InternalFieldCount = 1创建一个ObjectTemplate(可能通过FunctionTemplate)并将cpp对象作为v8 :: External抛出。
然后在ObjectTemplate上调用SetAccessor,其中包含您希望与您的数据成员对应的javascript属性的名称(可能是相同的名称,但您必须小心javascript保留字),以及检索它的函数。在该函数中,您从内部字段获取cpp对象,并使用它返回数据成员的值,并以任何您想要的格式将其返回到javascript。
然后,当您使用ObjectTemplate创建对象(ObjectTemplate::NewInstance()
)时,您必须通过v8::Object::SetInternalField()
调用将相应的cpp对象放入其内部字段。
以下代码未经过测试,但应该非常接近:
void getter_function(Local< String > property, const PropertyCallbackInfo< Value > &info) {
Person * person = static_cast<Person*>(info.This().GetInternalField(0));
info.GetReturnValue().Set(v8::String::NewFromUtf8(person->name.c_str()));
}
auto obj_template = v8::ObjectTemplate::New(a_v8_isolate);
obj_template.SetAccessor(v8::String::NewFromUtf8(a_v8_isolate, "name"), getter_function /* setter is optional */);
auto js_obj = my_object_template.NewInstance(a_v8_context);
js_obj.SetInternalField(new Person());
我也写了一个库来执行此操作:https://github.com/xaxxon/v8toolkit但是pmed可能更稳定。我有一些疯狂的东西,像clang c ++编译器的插件,自动读取你的源代码并自动为你的c ++类生成绑定。