2015-10-16 73 views
3

我有以下的代码几乎工件上用C++写:C++范围和谷歌的V8脚本上下文

[..] 

Handle<Object> jsGlobal; 
Handle<Function> jsUpdateFunc; 

void setupJs() { 
    V8::Initialize(); 
    Isolate* isolate = v8::Isolate::New(); 
    Isolate::Scope isolate_scope(isolate); 
    HandleScope handle_scope(isolate); 
    Local<Context> context = Context::New(isolate); 
    Context::Scope context_scope(context); 
    Local<String> source = String::NewFromUtf8(isolate, "var a = 0; function test() { a++; return a.toString(); }"); 
    Local<Script> script = Script::Compile(source); 
    script->Run(); 

    jsGlobal = context->Global(); 
    Handle<Value> value = jsGlobal->Get(String::NewFromUtf8(isolate, "test")); 
    jsUpdateFunc = Handle<Function>::Cast(value); 
} 

void callJs() { 
    Handle<Value> args[0]; 
    Handle<Value> js_result = jsUpdateFunc->Call(jsGlobal, 0, args); 
    js_result->ToString(); 

    String::Utf8Value utf8(js_result); 
    printf("%s\n", *utf8); 
} 

[..] 

我具备的功能setupJs()设置的V8环境和callJs应该被称为多次(工作时,javascript脚本每次递增var a)。

如果我在setupJs把

Handle<Value> args[0]; 
Handle<Value> js_result = jsUpdateFunc->Call(jsGlobal, 0, args); 
js_result->ToString(); 

String::Utf8Value utf8(js_result); 
printf("%s\n", *utf8); 

,我可以看到函数S怎么叫,并打印 “1”。但是,如果我离开这个函数调用withing不同的功能稍后调用,我有一个段错误在该行Handle<Value> js_result = jsUpdateFunc->Call(jsGlobal, 0, args);

我检查了两者jsUpdateFunc和jsGlobal不是空指针

回答

4

您需要使用持续处理jsGlobaljsUpdateFunc。正常(本地)句柄在封闭v8::HandleScope被销毁时无效。

您还需要v8::Isolate指针的全局变量,另一个用于v8::Context的持久句柄。

以后要调用的脚本功能,您需要:

  1. 锁定分离(你真的应该在setupJs做的一样好;看到v8::Locker
  2. 输入分离(见v8::Isolate::Scope)。
  3. 建立句柄范围(请参阅v8::HandleScope)。
  4. 为上下文创建本地句柄。
  5. 输入上下文(请参阅v8::Context::Scope)。
  6. 创建本地手柄jsGlobaljsUpdateFunc
  7. 如上所述调用脚本函数。

查找v8::Persistent和V8头文件中的相关模板。