编译Node.js 14时出现v8::BackingStore无EmptyDeleter成员错误求助
解决Node.js 14构建时v8::BackingStore::EmptyDeleter不存在的编译错误
我正在构建以下C++代码:
#if _MSC_VER && NODE_RUNTIME_ELECTRON && NODE_MODULE_VERSION >= 89 v8::Local<v8::Object> bufferView; bufferView = node::Buffer::New(Isolate::GetCurrent(), point_transfer_buffer, 0, 2 * sizeof(uint32_t)).ToLocalChecked(); auto js_point_transfer_buffer = node::Buffer::Data(bufferView); #elif V8_MAJOR_VERSION >= 8 auto backing_store = ArrayBuffer::NewBackingStore(point_transfer_buffer, 2 * sizeof(uint32_t), BackingStore::EmptyDeleter, nullptr); auto js_point_transfer_buffer = ArrayBuffer::New(Isolate::GetCurrent(), std::move(backing_store)); #else auto js_point_transfer_buffer = ArrayBuffer::New(Isolate::GetCurrent(), point_transfer_buffer, 2 * sizeof(uint32_t)); #endif
使用命令npx prebuild -r --strip可成功为Electron 16至23及Node.js 12、16、18版本构建,但执行npx prebuild -t 14.0.0 --strip时出现如下错误:
CC(target) Release/obj.target/tree_sitter/vendor/tree-sitter/lib/src/lib.o LIBTOOL-STATIC Release/tree_sitter.a CXX(target) Release/obj.target/tree_sitter_runtime_binding/src/binding.o CXX(target) Release/obj.target/tree_sitter_runtime_binding/src/conversions.o ../src/conversions.cc:38:114: error: no member named 'EmptyDeleter' in 'v8::BackingStore' auto backing_store = ArrayBuffer::NewBackingStore(point_transfer_buffer, 2 * sizeof(uint32_t), BackingStore::EmptyDeleter, nullptr); ~~~~~~~~~~~~~~^ 1 error generated. make: *** [Release/obj.target/tree_sitter_runtime_binding/src/conversions.o] Error 1
问题原因
Node.js 14对应的V8版本是8.4,而v8::BackingStore::EmptyDeleter是在V8 9.0及以上版本才引入的静态成员。当前代码仅判断V8_MAJOR_VERSION >=8,导致Node.js14(V8 8.x)错误进入了使用EmptyDeleter的分支,引发编译失败。
修复方案
细化版本判断逻辑,区分V8 8.x和更高版本:
#if _MSC_VER && NODE_RUNTIME_ELECTRON && NODE_MODULE_VERSION >= 89 v8::Local<v8::Object> bufferView; bufferView = node::Buffer::New(Isolate::GetCurrent(), point_transfer_buffer, 0, 2 * sizeof(uint32_t)).ToLocalChecked(); auto js_point_transfer_buffer = node::Buffer::Data(bufferView); #elif V8_MAJOR_VERSION >= 9 auto backing_store = ArrayBuffer::NewBackingStore(point_transfer_buffer, 2 * sizeof(uint32_t), BackingStore::EmptyDeleter, nullptr); auto js_point_transfer_buffer = ArrayBuffer::New(Isolate::GetCurrent(), std::move(backing_store)); #elif V8_MAJOR_VERSION >= 8 // 针对V8 8.x(Node.js14)手动传递空删除器 auto backing_store = ArrayBuffer::NewBackingStore( point_transfer_buffer, 2 * sizeof(uint32_t), [](void*, void*) {}, // 空删除器函数 nullptr ); auto js_point_transfer_buffer = ArrayBuffer::New(Isolate::GetCurrent(), std::move(backing_store)); #else auto js_point_transfer_buffer = ArrayBuffer::New(Isolate::GetCurrent(), point_transfer_buffer, 2 * sizeof(uint32_t)); #endif
或者也可以直接通过NODE_MODULE_VERSION判断Node.js版本(Node.js14的NODE_MODULE_VERSION为83):
#if _MSC_VER && NODE_RUNTIME_ELECTRON && NODE_MODULE_VERSION >= 89 v8::Local<v8::Object> bufferView; bufferView = node::Buffer::New(Isolate::GetCurrent(), point_transfer_buffer, 0, 2 * sizeof(uint32_t)).ToLocalChecked(); auto js_point_transfer_buffer = node::Buffer::Data(bufferView); #elif NODE_MODULE_VERSION >= 89 // Node.js16+ / Electron16+ auto backing_store = ArrayBuffer::NewBackingStore(point_transfer_buffer, 2 * sizeof(uint32_t), BackingStore::EmptyDeleter, nullptr); auto js_point_transfer_buffer = ArrayBuffer::New(Isolate::GetCurrent(), std::move(backing_store)); #elif NODE_MODULE_VERSION >= 83 // Node.js14 auto backing_store = ArrayBuffer::NewBackingStore( point_transfer_buffer, 2 * sizeof(uint32_t), [](void*, void*) {}, nullptr ); auto js_point_transfer_buffer = ArrayBuffer::New(Isolate::GetCurrent(), std::move(backing_store)); #else auto js_point_transfer_buffer = ArrayBuffer::New(Isolate::GetCurrent(), point_transfer_buffer, 2 * sizeof(uint32_t)); #endif
内容的提问来源于stack exchange,提问作者user3064538
相关产品推荐
相关产品推荐

