问题
在使用 Electron 21.0.0 及以上版本开发桌面应用程序时,调用 C++ 库时出现错误。报错信息如下:
App threw an error during load
Error: Error in native callback
at process.func [as dlopen] (node:electron/js2c/asar_bundle:2:1822)
原因分析
Electron 团队在 2022 年 6 月 30 日发布了一篇博客文章《Electron 和 V8 内存隔离区》。文中提到:
Electron 21 及更高版本将启用 V8 内存隔离区,这将对一些原生模块产生影响。
Electron 21 及更高版本启用了 V8 内存隔离区(也称 V8 沙箱)。尽管它具有沙箱的标签,但它与 Chromium 的渲染器沙箱完全不同。V8 内存隔离区的目标是:
假设攻击者可以在虚拟地址空间的专用区域(沙箱)内任意读写内存,例如包含所有 V8 堆。这种能力可以从典型的 V8 漏洞中获得。为了保护同一进程中的其他内存免受损坏,并通过扩展防止任意代码的执行,V8 堆中的所有原始指针都是“沙箱化”的,例如通过将它们转换为相对于沙箱底部的偏移量或转换为索引进入外部指针表。
官方github中的issue讨论
[Bug]: Electron 21 breaks node-api stability guarantees #35801
打开
- https://github.com/electron/electron/issues/35801
解决方案
方案1:禁用 V8 内存隔离区
既然这个问题是因为启用 V8 内存隔离区导致的,那么可以考虑重新编译electron禁用 V8 内存隔离区。
这个整体难度系数较高
方案2:降级 Electron 版本👍
将 Electron 降级至 21 版本之前,避免使用 V8 内存隔离区。
目前我在使用的正是20.3.8
版本,如果你是复杂的monorepo项目,建议你在降版本后主动查看一下electron的版本号,查看的命令如下
console.log(process.versions.electron);
https://stackoverflow.com/questions/75668307/error-in-native-callback-using-ffi-napi-in-electron-and-electron-builder
方案3:学习 VS Code 的解决方案
打开vscode
的官方github
我检索到一个已经关闭的
RFC: Plan for updating to Electron >= 21 without compromising extension host stability
https://github.com/microsoft/vscode/issues/177338
链接: issue #177338
VS Code 也基于 Electron 开发,它的解决方案是:
使用内存分配器 shim 将扩展主机的堆分配重新路由到 V8 沙箱内部的分区。
总结
本文分析了在 Electron 23 及以上版本使用 C++ 库时出现的 native callback 错误,归因于 V8 内存隔离区的启用。文中提出了禁用 V8 内存隔离区、降级 Electron 版本、以及学习 VS Code 的解决方案等三种解决思路。希望这些建议能为 Electron 开发者解决此类问题提供参考。