添加新模块实例时 V8PP / V8 崩溃
V8PP / V8 crashing when adding a new module instance
我希望能够创建 C++ classes 并将它们公开到 V8 JavaScript 引擎中。我用的是v8pp library to do this, and by following their examples as well as the Google V8 Hello World Script,我已经到了这个代码
main.cpp
文件
TestClass1.h
- 我想向 JavaScript 公开其 class
CMakeList.txt
文件 - 如果这很重要,您可以看到我是如何链接 V8 的):
// main.cpp
#define V8_COMPRESS_POINTERS
#include <v8.h>
#include <libplatform.h>
#include <v8pp/module.hpp>
#include <v8pp/class.hpp>
#include "src/TestClass1.h"
int main(int argc, char* argv[]) {
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();
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
v8::Isolate *isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8pp::module window(isolate);
v8pp::class_<TestClass1> TestClass1_V8(isolate);
TestClass1_V8
.ctor<int, int>()
.set("a", v8pp::property(&TestClass1::getA, &TestClass1::setA))
.set("b", v8pp::property(&TestClass1::getB, &TestClass1::setB))
//.set_static("c", 5, true)
.set("methodA", &TestClass1::testMethod);
window.set("TestClass1", TestClass1_V8);
isolate->GetCurrentContext()->Global()->Set(isolate->GetCurrentContext(), v8pp::to_v8(isolate, "window"), window.new_instance());
v8::Context::Scope context_scope(context);
{
v8::Local<v8::String> source = v8::String::NewFromUtf8Literal(isolate, "(function() {let t = new window.TestClass1(); t.a = 5; return t.a})()");
v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked();
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
v8::String::Utf8Value utf8(isolate, result);
printf("%s\n", *utf8);
}
}
return 0;
}
// src/TestClass1.h
#ifndef V8PP_TESTCLASS1_H
#define V8PP_TESTCLASS1_H
class TestClass1 {
friend int main(int argc, char* argv[]);
public:
static int m_c;
TestClass1(int a, int b) {
m_a = a;
m_b = b;
}
int testMethod(int c) {
return m_a + m_b + c;
}
private:
int m_a;
int m_b;
int getA() {
return m_a;
}
void setA(int a) {
m_a = 2 * a;
}
int getB() {
return m_b;
}
void setB(int b) {
m_b = 3 + b;
}
};
#endif //V8PP_TESTCLASS1_H
# CMakeList.txt
cmake_minimum_required(VERSION 3.19)
project(V8PP)
set(CMAKE_CXX_STANDARD 20)
### V8 ### [MANUAL]
set(CMAKE_CXX_FLAGS "/MT")
set(CMAKE_C_FLAGS "/MT")
if(MSVC)
add_compile_options(
$<$<CONFIG:>:/MT> #---------|
$<$<CONFIG:Debug>:/MTd> #---|-- Statically link the runtime libraries
$<$<CONFIG:Release>:/MT> #--|
)
endif()
include_directories(E:/V8/depot_tools/v8/include)
include_directories(E:/V8/depot_tools/v8/include/libplatform)
include_directories(${CMAKE_SOURCE_DIR}/v8pp-master/v8pp-master)
link_directories(E:/V8/depot_tools/v8/out.gn/x64.release/obj/)
link_directories(E:/V8/depot_tools/v8/out.gn/x64.release/obj/third_party)
link_directories(E:/V8/depot_tools/v8/out.gn/x64.release/obj/third_party/icu)
link_libraries(
v8_libbase
v8_libplatform
v8_monolith
icuuc
icui18n
)
link_libraries(winmm.lib)
link_libraries(dbghelp.lib)
link_libraries(shlwapi.lib)
### V8 ###
add_executable(V8PP main.cpp)
我已将错误隔离到行
isolate->GetCurrentContext()->Global()->Set(isolate->GetCurrentContext(), v8pp::to_v8(isolate, "window"), window.new_instance());
特别是 window.new_instance()
。进入 v8pp
源代码(文件 module.hpp
),方法中唯一的一行是
return obj_->NewInstance(isolate_->GetCurrentContext()).ToLocalChecked();
我将不同的语句分成不同的行,错误来自 obj_->NewInstance()
,其中 obj_
是一个 v8::Local<v8::ObjectTemplate>
,在构造函数的初始化列表中创建模块对象。这个函数调用是v8本身的一部分,但我只能访问v8的头文件,所以我不知道是什么导致了错误。
代码构建良好,但是当它是 运行 时,没有回溯,只是:
Process finished with exit code -1073741819 (0xC0000005)
暗示内存访问错误(可能与指针有关?)
有谁知道如何在不发生此崩溃的情况下将 v8pp module
的新实例添加到 v8 引擎中?
编辑
使用:
- Windows 10
- C++ 20
- CMake(在 CLion 上)
- MSVC 2019 64 位
我发现了问题:首先,我必须移动代码行
v8::Context::Scope context_scope(context);
到直下线
v8::Local<v8::Context> context = v8::Context::New(isolate);
这确实造成了另一个错误
#
# Fatal error in v8::ToLocalChecked
# Empty MaybeLocal.
#
<unknown>:21: Uncaught argument count does not match function definition
这是因为我在JavaScript中调用构造函数时忘记添加参数,所以将JavaScript代码更改为
(function() {let t = new window.TestClass1(); t.a = 5; return t.a;})()
一切正常。
我希望能够创建 C++ classes 并将它们公开到 V8 JavaScript 引擎中。我用的是v8pp library to do this, and by following their examples as well as the Google V8 Hello World Script,我已经到了这个代码
main.cpp
文件TestClass1.h
- 我想向 JavaScript 公开其 class
CMakeList.txt
文件 - 如果这很重要,您可以看到我是如何链接 V8 的):
// main.cpp
#define V8_COMPRESS_POINTERS
#include <v8.h>
#include <libplatform.h>
#include <v8pp/module.hpp>
#include <v8pp/class.hpp>
#include "src/TestClass1.h"
int main(int argc, char* argv[]) {
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();
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
v8::Isolate *isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8pp::module window(isolate);
v8pp::class_<TestClass1> TestClass1_V8(isolate);
TestClass1_V8
.ctor<int, int>()
.set("a", v8pp::property(&TestClass1::getA, &TestClass1::setA))
.set("b", v8pp::property(&TestClass1::getB, &TestClass1::setB))
//.set_static("c", 5, true)
.set("methodA", &TestClass1::testMethod);
window.set("TestClass1", TestClass1_V8);
isolate->GetCurrentContext()->Global()->Set(isolate->GetCurrentContext(), v8pp::to_v8(isolate, "window"), window.new_instance());
v8::Context::Scope context_scope(context);
{
v8::Local<v8::String> source = v8::String::NewFromUtf8Literal(isolate, "(function() {let t = new window.TestClass1(); t.a = 5; return t.a})()");
v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked();
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
v8::String::Utf8Value utf8(isolate, result);
printf("%s\n", *utf8);
}
}
return 0;
}
// src/TestClass1.h
#ifndef V8PP_TESTCLASS1_H
#define V8PP_TESTCLASS1_H
class TestClass1 {
friend int main(int argc, char* argv[]);
public:
static int m_c;
TestClass1(int a, int b) {
m_a = a;
m_b = b;
}
int testMethod(int c) {
return m_a + m_b + c;
}
private:
int m_a;
int m_b;
int getA() {
return m_a;
}
void setA(int a) {
m_a = 2 * a;
}
int getB() {
return m_b;
}
void setB(int b) {
m_b = 3 + b;
}
};
#endif //V8PP_TESTCLASS1_H
# CMakeList.txt
cmake_minimum_required(VERSION 3.19)
project(V8PP)
set(CMAKE_CXX_STANDARD 20)
### V8 ### [MANUAL]
set(CMAKE_CXX_FLAGS "/MT")
set(CMAKE_C_FLAGS "/MT")
if(MSVC)
add_compile_options(
$<$<CONFIG:>:/MT> #---------|
$<$<CONFIG:Debug>:/MTd> #---|-- Statically link the runtime libraries
$<$<CONFIG:Release>:/MT> #--|
)
endif()
include_directories(E:/V8/depot_tools/v8/include)
include_directories(E:/V8/depot_tools/v8/include/libplatform)
include_directories(${CMAKE_SOURCE_DIR}/v8pp-master/v8pp-master)
link_directories(E:/V8/depot_tools/v8/out.gn/x64.release/obj/)
link_directories(E:/V8/depot_tools/v8/out.gn/x64.release/obj/third_party)
link_directories(E:/V8/depot_tools/v8/out.gn/x64.release/obj/third_party/icu)
link_libraries(
v8_libbase
v8_libplatform
v8_monolith
icuuc
icui18n
)
link_libraries(winmm.lib)
link_libraries(dbghelp.lib)
link_libraries(shlwapi.lib)
### V8 ###
add_executable(V8PP main.cpp)
我已将错误隔离到行
isolate->GetCurrentContext()->Global()->Set(isolate->GetCurrentContext(), v8pp::to_v8(isolate, "window"), window.new_instance());
特别是 window.new_instance()
。进入 v8pp
源代码(文件 module.hpp
),方法中唯一的一行是
return obj_->NewInstance(isolate_->GetCurrentContext()).ToLocalChecked();
我将不同的语句分成不同的行,错误来自 obj_->NewInstance()
,其中 obj_
是一个 v8::Local<v8::ObjectTemplate>
,在构造函数的初始化列表中创建模块对象。这个函数调用是v8本身的一部分,但我只能访问v8的头文件,所以我不知道是什么导致了错误。
代码构建良好,但是当它是 运行 时,没有回溯,只是:
Process finished with exit code -1073741819 (0xC0000005)
暗示内存访问错误(可能与指针有关?)
有谁知道如何在不发生此崩溃的情况下将 v8pp module
的新实例添加到 v8 引擎中?
编辑
使用:
- Windows 10
- C++ 20
- CMake(在 CLion 上)
- MSVC 2019 64 位
我发现了问题:首先,我必须移动代码行
v8::Context::Scope context_scope(context);
到直下线
v8::Local<v8::Context> context = v8::Context::New(isolate);
这确实造成了另一个错误
#
# Fatal error in v8::ToLocalChecked
# Empty MaybeLocal.
#
<unknown>:21: Uncaught argument count does not match function definition
这是因为我在JavaScript中调用构造函数时忘记添加参数,所以将JavaScript代码更改为
(function() {let t = new window.TestClass1(); t.a = 5; return t.a;})()
一切正常。