如何在V8中公开c++类成员
How to expose C++ class member in V8
我想在v8中暴露c++类成员,我知道如何暴露类方法,但我不知道如何暴露类成员。
c++类:class Person{
public:
string name;
}
Javascript: var p1 = new Person();
p1.name = "Jack";
我想做到这一点,这是可能的。谢谢!
您可以使用SetAccessor()
作为Person原型模板,提供成员指针作为外部V8数据。但是你需要将Person的c++实例包装成V8对象,然后在访问器getter/setter回调中将这个V8对象解包装回c++对象。this ()
在我的v8pp
库中使用这种方式。该库简化了c++类和函数对V8的暴露。对于类成员变量,它看起来像这样:
v8pp::class_<Person> Person_class(isolate);
Person_class
// bind member variable
.set("name", &Person::name)
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++类生成绑定。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 助记符和指向成员语法的指针
- 用于访问容器<T>数据成员的正确 API
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 嵌套在类中时无法设置成员数据
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 将函数类成员映射到类本身内部
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 将公共但非静态的成员函数与ALGLIB集成
- 多成员Constexpr结构初始化
- 我们可以访问一个不存在的联盟的成员吗