c++作用域和Google V8脚本上下文

C++ scope and Google V8 script context

本文关键字:脚本 上下文 V8 Google 作用域 c++      更新时间:2023-10-16

我用c++编写了下面这段几乎可以工作的代码:

[..]
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("%sn", *utf8);
}
[..]

我有函数setupJs()设置v8环境和callJs应该被多次调用(工作时,javascript脚本每次递增var a)。

如果我把

Handle<Value> args[0];
Handle<Value> js_result = jsUpdateFunc->Call(jsGlobal, 0, args);
js_result->ToString();
String::Utf8Value utf8(js_result);
printf("%sn", *utf8);

在setupJs中,我可以看到函数是如何被调用和"1"被打印出来的。但是,如果我在稍后调用的不同函数中离开函数调用,则在Handle<Value> js_result = jsUpdateFunc->Call(jsGlobal, 0, args);

行有段错误。

我已经检查过了,jsUpdateFunc和jsGlobal都是非空指针

您需要为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头文件中查找v8::Persistent和相关模板