拜访V8专家。我将V8嵌入到我的项目中,并且遇到了将代码模块化的问题。最简单的例子是编译并运行一个小的脚本,该脚本显示“ Hello World!”。从C ++函数。工作版本如下:
void testV8(const v8::FunctionCallbackInfo<v8::Value>& args) {
printf("Hello World!\n");
}
void working() {
v8::Isolate* isolate = nullptr;
std::string code = "testV8();";
{
// Basic initialization
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
v8::Isolate::CreateParams initOptions;
initOptions.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
isolate = v8::Isolate::New(initOptions);
isolate->Enter();
// Create context
v8::HandleScope handleScope(isolate);
auto global = v8::ObjectTemplate::New(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);
// Enter context
v8::Context::Scope contextScope(context);
// Bind function
v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(isolate, &testV8);
auto name = v8::String::NewFromUtf8(isolate, "testV8").ToLocalChecked();
context->Global()->Set(context, name, ft->GetFunction(context).ToLocalChecked());
// Run script
auto execCode = v8::String::NewFromUtf8(isolate, code.c_str()).ToLocalChecked();
v8::Local<v8::Script> script;
if (v8::Script::Compile(context, execCode).ToLocal(&script)) {
v8::Local<v8::Value> result;
script->Run(context).ToLocal(&result);
}
}
}
[当我尝试将代码分成可管理的范围(模仿我稍后要构建的包装器类时,在脚本编译时会崩溃:
void testV8(const v8::FunctionCallbackInfo<v8::Value>& args) {
printf("Hello World!\n");
}
void failing() {
v8::Isolate* isolate = nullptr;
std::string code = "testV8();";
v8::Persistent<v8::Context> persistentContext;
{
// Basic initialization
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
v8::Isolate::CreateParams initOptions;
initOptions.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
isolate = v8::Isolate::New(initOptions);
isolate->Enter();
// Create context
v8::HandleScope handleScope(isolate);
auto global = v8::ObjectTemplate::New(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);
// Save context
persistentContext.Reset(isolate, context);
}
{
// Rebuild scopes and enter context
v8::Locker locker(isolate);
v8::HandleScope handleScope(isolate);
v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate, persistentContext);
v8::Context::Scope contextScope(context);
// Bind function
v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(isolate, &testV8);
auto name = v8::String::NewFromUtf8(isolate, "testV8").ToLocalChecked();
context->Global()->Set(context, name, ft->GetFunction(context).ToLocalChecked());
}
{
// Rebuild scopes and enter context
v8::Locker locker(isolate);
v8::HandleScope handleScope(isolate);
v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate, persistentContext);
v8::Context::Scope contextScope(context);
// Run script
auto execCode = v8::String::NewFromUtf8(isolate, code.c_str()).ToLocalChecked();
v8::Local<v8::Script> script;
if (v8::Script::Compile(context, execCode).ToLocal(&script)) {
v8::Local<v8::Value> result;
script->Run(context).ToLocal(&result);
}
}
}
基于xCode构建,并在Macbook上的此代码上运行。我无法判断我做错了什么还是上下文是否有错误。在线研究使我相信,以这种方式使用持久性上下文可以使作用域之间的相同上下文保持活动状态。这是怎么了?
问题是,作用域结束后,平台的unique_ptr将被销毁。将其移至父范围可对其进行修复。