首页 > 解决方案 > 如果未在 main 中输入隔离,则 V8 异常

问题描述

如果我有一个初始化 V8、隔离等的类 System,那么我主要做的是:

int main(int argc, char *argv[]) {
    System system {};  // initializes v8
    system.callJsFunction();
}

尝试调用 JS 时出现异常Function。是的,该函数存储为Persistent<Function>. 但是,如果我初始化 v8 并在 main 中输入隔离范围:

int main(int argc, char *argv[]) {
  // initialize V8
  v8::V8::InitializeICUDefaultLocation(argv[0]);
  v8::V8::InitializeExternalStartupData(argv[0]);
  std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
  v8::V8::InitializePlatform(platform.get());
  v8::V8::Initialize();

  // Create the isolate
  Isolate::CreateParams create_params;
  create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
  Isolate *isolate = Isolate::New(create_params);

  // Enter the isolate scope
  Isolate::Scope isolate_scope(isolate);

  System system {};
  system.callJsFunction();
}

它完美地工作。那么问题来了,如何在系统的构造函数中进入隔离作用域,并在程序的整个执行过程中保持在其中。我试图手动Enter输入它,但它不起作用。隔离当然存储在 System 的成员中,因此我可以访问它。

标签: c++v8

解决方案


如果您查看 的定义Isolate::Scope,您会发现它只是isolate->Enter()在其构造函数和isolate->Exit()析构函数中所做的一个小便利。它存在的原因是您通常希望这些调用成对发生(可能是嵌套的),而这样的帮助对象是确保这一点的最简单和最安全的方法(类似于“RAII”模式)。

因此,如果您有更复杂的生命周期管理要求,您可以Isolate::Scope完全放弃,只需在正确的时间手动Enter()调用。Exit()

也就是说,你只是说你“得到一个异常”而没有提供任何关于问题类型的进一步细节(它真的是一个异常吗?还是断言失败?或者崩溃/段错误?),所以上面可能会也可能不会成为问题。请发布一个完整的示例,以及有关您遇到的问题类型的更多详细信息(错误消息?堆栈跟踪?)。如果您还没有这样做,编译 Debug 构建并在您选择的调试器中运行它也可能提供有价值的见解——您甚至可以看到问题所在;-)


推荐阅读