electron 调用 dll(动态链接库)

因业务原因需要调用dll文件,记录一下踩坑的过程

(1)坑一:ffi和ref这两个库不支持node10以上的版本

安装报错信息:

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! ref@1.3.5 install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the ref@1.3.5 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

解决方案:用ffi-napi和ref-napi这两个库进行替代

贴上安装代码

npm i ffi-napi
npm i ref-napi

(2)坑二:安装 windows-build-tools卡在Successfully installed Python 2.7

描述: node-gyp和windows-build-tools是动态库的构建工具
安装报错:卡在Successfully installed Python 2.7不动

解决方案:在用户数据文件夹%USERPROFILE%\ AppData \ Local \ Temp创建一个名为dd_client_.log的文件,编辑该文件,加入一行Closing installer. Return code: 3010.然后保存

(3)坑三:python版本不对导致安装依赖库失败

解决方案:切换python版本

(4)坑四:ref-array不支持node10以上的版本

用途:ref-array该模块使用 ref“type”接口在 Node.js 缓冲区之上提供“数组”实现(简单来说就是入参或返回值是数组时用到)

安装报错信息:

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! ref@1.3.5 install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the ref@1.3.5 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

解决方案:用ref-array-di这个库进行替代

贴上安装使用代码

npm i ref-array-di
const ref = require('ref-napi')
const refArray = require('ref-array-di')(ref)

refArray('string')

(5)坑五:调用的dll还有其他依赖dll,没有全部拷进去项目导致的报错,这个错误比较明显,在报错信息里就可以看出来

(6)坑六:Dynamic Linking Error: Win32 Error 126

解决方案:vue.config.js中添加externals配置

module.exports = {
	...,
  pluginOptions: {
    electronBuilder: {
      preload: 'src/preload.js',
      // 配置
      externals: ['ffi-napi', 'ref-napi'],
    }
  }
}

(7)坑七:子进程/工作线程 开发环境找得到模块,electron打包后生产环境找不到模块cannot find module XXX

原因:子进程/工作线程和主进程具有不同的执行环境和工作目录
解决方案:安装对应模块并设置asarUnpack

  pluginOptions: {
    electronBuilder: {
      preload: 'src/preload.js',
      // 配置
      externals: ['ffi-napi', 'ref-napi'],
      builderOptions: {
        // 指定创建asar存档时要解压的文件,解决合成子线程的依赖包找不到的问题
        asarUnpack: [
          './node_modules/ffi-napi/**/*',
          './node_modules/ref-napi/**/*',
          './node_modules/debug/**/*',
          './node_modules/ms/**/*',
          './node_modules/node-gyp-build/**/*',
          './node_modules/ref-struct-di/**/*',
        ],

配置后依赖包的放置位置
在这里插入图片描述

(8)坑八:使用node子进程spawn打包后提示需要node环境

解决方案:改用fork

const child = fork(childProcessPath, [], {})

(9)坑九:使用node工作线程worker.terminate()停止线程后electron应用直接闪退

原因:electron框架bug,估计已解决,但版本不能轻易更换
解决方案:改用node子进程

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Electron 框架基于 Node.js 和 Chromium,可以使用 Node.js 的 `child_process` 模块来调用系统的 DLL 库。 首先,需要在 Electron 项目中安装 `ffi` 和 `ref` 两个 Node.js 模块,用于调用 DLL 库和处理数据类型。 然后,可以使用以下代码来调用 DLL 库: ```javascript const ffi = require('ffi'); const ref = require('ref'); const path = require('path'); // 定义 DLL 函数的参数类型和返回值类型 const intPtr = ref.refType('int'); const doublePtr = ref.refType('double'); const dll = ffi.Library(path.join(__dirname, 'example.dll'), { 'add': ['int', ['int', 'int']], 'multiply': ['double', ['double', 'double', doublePtr]], 'sort': ['void', [intPtr, 'int']] }); // 调用 DLL 函数 const result1 = dll.add(1, 2); console.log(result1); // 输出 3 const result2 = ref.alloc('double'); const result3 = dll.multiply(2.5, 3.5, result2); console.log(result3, result2.deref()); // 输出 8.75 8.75 const array = [3, 1, 4, 1, 5, 9]; const buffer = Buffer.alloc(array.length * ref.sizeof.int); array.forEach((value, index) => { buffer.writeInt32LE(value, index * ref.sizeof.int); }); dll.sort(buffer, array.length); console.log(buffer); // 输出 <Buffer 01 01 03 04 05 09> ``` 在上面的代码中,`ffi.Library` 函数用于加载 DLL 库,并定义 DLL 函数的参数类型和返回值类型。然后,可以使用 `dll` 对象调用 DLL 函数。注意,DLL 函数的参数和返回值类型需要与定义的类型一致,可以使用 `ref.refType` 定义指针类型,使用 `ref.alloc` 创建指针变量,使用 `deref` 方法获取指针指向的值。在调用 DLL 函数时,需要将 JavaScript 数组转换为 C 数组,可以使用 `Buffer.alloc` 创建缓冲区,使用 `writeInt32LE` 方法将数组元素写入缓冲区,然后将缓冲区的地址传递给 DLL 函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值