如何在V8中公开C ++类成员

时间:2016-09-01 09:21:57

标签: javascript c++ v8

我想在v8中公开C ++类成员,我知道如何公开类方法,但我不知道如何公开类成员。

C ++类:

class Person{
public:
string name;
}

使用Javascript:

var p1 = new Person();
p1.name = "Jack";

我想实现这一目标,这是可能的。谢谢!

2 个答案:

答案 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 ++类生成绑定。

相关问题