【发布时间】:2016-05-23 12:52:47
【问题描述】:
也许这是个愚蠢的问题(我是 C++ 的新手,只是想将它用作 android 的库),但我无法多次运行某些 JS 的评估。
我从"hello world" 教程开始。但是后来我想要简单的事情,重新运行 main(只需将教程代码的内容包装到函数中并在新空的 main 中运行两次。
这是我得到的:
#
# Fatal error in ../src/isolate.cc, line 1868
# Check failed: thread_data_table_.
#
==== C stack trace ===============================
1: 0xa890b9
2: 0x6a22fc
3: 0x42694f
4: 0x405f66
5: 0x405ec7
6: __libc_start_main
7: 0x405dc9
Illegal instruction (core dumped)
这是在创建新的隔离之后发生的
Isolate* isolate = Isolate::New(create_params);
好吧,我该怎么办?我是否使用了错误的构造?我应该关闭/删除/清除更多内容吗?
从更大的角度来看,我只想做评估功能,可以多次触发,除此之外还在同一上下文中运行多个 js 片段(如何拆分此功能?)。
有什么想法吗?
更新:
好的,可以说主要可以分为三个逻辑部分:
初始化
int main(int argc, char* argv[]) {
// Initialize V8.
V8::InitializeICU();
V8::InitializeExternalStartupData(argv[0]);
Platform* platform = platform::CreateDefaultPlatform();
V8::InitializePlatform(platform);
V8::Initialize();
// Create a new Isolate and make it the current one.
ArrayBufferAllocator allocator;
Isolate::CreateParams create_params;
create_params.array_buffer_allocator = &allocator;
评估
Isolate* isolate = Isolate::New(create_params);
{
Isolate::Scope isolate_scope(isolate);
// Create a stack-allocated handle scope.
HandleScope handle_scope(isolate);
// Create a new context.
Local<Context> context = Context::New(isolate);
// Enter the context for compiling and running the hello world script.
Context::Scope context_scope(context);
// Create a string containing the JavaScript source code.
Local<String> source =
String::NewFromUtf8(isolate, "'Hello' + ', World!'",
NewStringType::kNormal).ToLocalChecked();
// Compile the source code.
Local<Script> script = Script::Compile(context, source).ToLocalChecked();
// Run the script to get the result.
Local<Value> result = script->Run(context).ToLocalChecked();
// Convert the result to an UTF8 string and print it.
String::Utf8Value utf8(result);
printf("%s\n", *utf8);
}
isolate->Dispose();
和干净
// Dispose and tear down V8.
V8::Dispose();
V8::ShutdownPlatform();
delete platform;
return 0;
现在正如我之前所说,如果我运行 main contains init->evaluation->clean 两次,这意味着 init->evaluation- >clean->init->evaluation->clean,则出现错误。我发现,如果我将 evaluation 部分提取到单独的函数中,我可以多次运行它,例如作为 init->(evaluation){2}->clean
它应该如何工作?下一步是将这个主要分成树分离功能,这意味着我必须有平台的静态成员?它会以某种方式导致泄漏吗?
注意: 我想从 android 运行它,这意味着例如点击 UI,通过 JNI 将 js 源传播到 C 中,然后调用已经初始化或未初始化的 c++ V8。嗯?
首选的方式是拥有“黑匣子”,但如果我必须持有平台,那就这样吧。如果不重新初始化 V8,它可能也会更快,对吧?
更新 2:
好吧,拆分评估部分以在同一隔离/上下文中实现多次运行仍然存在问题。
我在使用存储的隔离和上下文创建上下文后将其拆分,但没有运气。在第二部分尝试创建源字符串时,它失败了,可能是因为使用了存储的隔离(我猜是隔离范围的东西)。
:(
【问题讨论】:
-
我认为我们需要更多的上下文,而不仅仅是
Isolate::New。 -
@MSalters 请查看更新 :)
-
嗨@ThinkDeep 我也遇到了同样的问题,你能粘贴完整的代码吗?谢谢。
标签: javascript android c++ v8