我想在使用v8引擎的嵌入式JavaScript应用程序中实现此功能。
function myFunction1() {
//do stuff
}
function myFunction2() {
//do other stuff
}
myAddon.addCallback(myFunction1);
myAddon.addCallback(myFunction2);
myAddon.removeCallback(myFunction1);
为了做到这一点,我需要将这些功能存储在std::set
中,如此
void addCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(args.GetIsolate());
v8::Local<v8::Function> cb = v8::Local<v8::Function>::Cast(args[0]);
std::set mySet = this->mySet;
//now how do I insert a reference to this function into mySet so I can retrieve
//it later
}
void removeCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(args.GetIsolate());
v8::Local<v8::Function> cb = v8::Local<v8::Function>::Cast(args[0]);
std::set mySet = this->mySet;
//now how do I remove the element in this set that refers to this function?
}
如何做到这一点?我不想使用v8::Object::GetIdentityHash()
因为结果不能保证是唯一的。
我也不能只在std::set
中存储Local,因为复制构造函数是私有的,一旦removeCallback或addCallback返回它也会被描述。
感谢您提前提供任何帮助。
编辑:我意识到我可以编写一些javascript来为我执行函数哈希,然后调用一个C ++绑定函数来迭代所有回调,但是我不想每次需要存储集合时都这样做JavaScript对象的哈希。
答案 0 :(得分:4)
这是正确的,你不能安全地存储Local<T>
句柄,因为当它超出范围时,你的函数对象可能变得可用于垃圾收集。你需要的是一个持久的句柄。您可以从本地构建它:
v8::Local<v8::Function> cb = v8::Local<v8::Function>::Cast(args[0]);
v8::Persistent<v8::Function, v8::CopyablePersistentTraits<v8::Function>> value(isolate, cb);
注意允许句柄复制的CopyablePersistentTraits
。如果您想阻止它,还有NonCopyablePersistentTraits
。
现在你可以把它放在一个矢量中:
std::vector<v8::Persistent<v8::Function, v8::CopyablePersistentTraits<v8::Function>>> v;
v.push_back(value);
转换回本地:
v8::Local<v8::Function> local = v8::Local<v8::Function>::New(isolate, value);
对于std::set
,您还需要为元素提供比较功能。将v8::Persistent<T>
包装到您自己的类中可能是个好主意,例如PersistentWrapper<T>
(这是我在我的项目中所做的)以获得所需的行为。