我正在尝试将v8静态库嵌入到我的独立C++应用程序中(macOS: Monterey 12.6,CPU:英特尔酷睿i7、Xcode:第13.1节(13 A1030 d))
1.我编写了一个简单的bash脚本来获取v8静态库:
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=$PWD/depot_tools:$PATH
mkdir v8
cd v8
fetch v8
cd v8
git checkout branch-heads/9.4
gclient sync
gn gen out/x64.release--args='
is_component_build = false
is_debug = false
target_cpu = "x64"
use_goma = false
v8_enable_backtrace = true
v8_enable_disassembler = true
v8_enable_object_print = true
v8_enable_verify_heap = true
dcheck_always_on = false
v8_monolithic = true
v8_use_external_startup_data = false'
ninja -C out/x64.release v8_monolith
1.将libv8_monolith.a、libv8_libplatform.a、libv8_libbase.a从out/x64.release/obj复制到我的xcode c控制台项目的文件夹,并将它们链接到该文件夹。
1.测试项目的c部分如下所示:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <filesystem>
#include <v8.h>
#include <libplatform/libplatform.h>
using namespace v8;
std::string ToStdString(v8::Isolate *isolate, v8::MaybeLocal<v8::Value> valueMaybe);
bool LoadScript(const std::string& path, Isolate* _isolate, Local<Context> _context);
void LogCallback(const FunctionCallbackInfo<Value> &args);
void CreateTrue(const FunctionCallbackInfo<Value> &args) {
v8::Isolate *isolate(args.GetIsolate());
args.GetReturnValue().Set(v8::True(isolate));
}
void CreateFalse(const FunctionCallbackInfo<Value> &args) {
v8::Isolate *isolate(args.GetIsolate());
args.GetReturnValue().Set(v8::False(isolate));
}
int main(int argc, const char * argv[]) {
std::unique_ptr<Platform> platform = v8::platform::NewDefaultPlatform();
V8::InitializePlatform(platform.get());
V8::Initialize();
Isolate::CreateParams create_params;
create_params.array_buffer_allocator = ArrayBuffer::Allocator::NewDefaultAllocator();
Isolate* isolate = Isolate::New(create_params);
Local<Context> context;
{
Locker l(isolate);
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
Local<ObjectTemplate> global = ObjectTemplate::New(isolate);
global->Set(isolate, "log", FunctionTemplate::New(isolate, LogCallback));
global->Set(isolate, "cpp_CreateTrue", FunctionTemplate::New(isolate, CreateTrue));
global->Set(isolate, "cpp_CreateFalse", FunctionTemplate::New(isolate, CreateFalse));
context = Context::New(isolate, nullptr, global);
auto jsLikeBool = v8::Boolean::New(isolate, true);
// at this point typeof this jsLikeBool equals to string, but should be equal to boolean
if (jsLikeBool->IsBoolean()) {
std::cout << "c++::GetBoolean jsLikeBoolean has boolean type" << std::endl;
} else {
std::cout << "c++::GetBoolean jsLikeBoolean DOES NOT have boolean type, but HAS: " << ToStdString(isolate, jsLikeBool->TypeOf(isolate)) << std::endl;
}
}
if (!LoadScript(std::filesystem::current_path() / "assets" / "bools.js", isolate, context)) {
return 1;
}
isolate->Dispose();
V8::Dispose();
V8::ShutdownPlatform();
delete create_params.array_buffer_allocator;
return 0;
}
1.资产/bools. js文件:
const Js_CreateTrue = () => true;
const Js_CreateFalse = () => false;
const CheckCreator = function(tag, getter, expectedType, expectedValue) {
const value = getter();
const valueType = typeof value;
if (valueType !== expectedType) {
log(`JS::test ${tag} failed types check, actual: ${valueType}, but expected: ${expectedType}`);
}
if (value !== expectedValue) {
log(`JS::test ${tag} failed values check, actual: ${value}, but expected: ${expectedValue}`);
}
}
CheckCreator("Js_CreateTrue", Js_CreateTrue, "boolean", true); // OK
CheckCreator("Js_CreateFalse", Js_CreateFalse, "boolean", false); // OK
CheckCreator("cpp_CreateTrue", cpp_CreateTrue, "boolean", true); // FAILED: gets an empty string
CheckCreator("cpp_CreateFalse", cpp_CreateFalse, "boolean", false); // causes crash in c++, actual type is `symbol`
我已经尝试了不同的标记/分支的v8源代码,没有帮助。如何摆脱这种奇怪的行为返回布尔从C++到JS?
1条答案
按热度按时间8zzbczxx1#
我稍后会仔细研究整个问题。至于标题中的具体问题,请看下文。
v8::ReturnValue<T>
有一个成员函数void Set(bool value)
。将布尔值设置为返回值的正确方法是