将句柄存储到hashmap中的对象或在Google的V8引擎中设置

时间:2014-01-20 16:30:34

标签: v8 embedded-v8

我想在使用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对象的哈希。

1 个答案:

答案 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>(这是我在我的项目中所做的)以获得所需的行为。