vlambda博客
学习文章列表

关于vue-electron环境下引入C++动态链接库那些事

本文大概内容包括nodejs调用C++动态链接库并使用动态库中的函数接口的具体方法以及遇到种种问题的处理方法。

一般调用外部C++动态链接库有两种方法:

  • 方案一:使用node-ffi,是使用纯JavaScript加载和调用动态库的node addon,它可以用来在不写任何C++代码的情况下调用动态链接库的API 接口。

  • 方案二:使用C++编写一个node addon,通过LoadLibrary调用dll。

先说一下方案一,方案二后期研究了之后再写。

  • 首先需要在node环境下安装ffi-napi或ffi第三方库,至于两个包的区别:

  • node-ffi:它负责处理跨JavaScript和C的类型转换,连接了C代码和JS代码, 通过内存共享来完成调用, 而内部又通过ref,ref-array和ref-struct来实现类型转换,普通类型(int,float,double,long等)、指针、结构体。

  • node-ffi-napi:是作者(node-ffi-napi)根据node-ffi修改而发布到npm仓库的, 可以直接通过npm安装, 支持node.js 12和electron高版本 。

安装方法:

yarn add ffi-napi或者npm install ffi-napi再或者cnpm install ffi-napi
  • 不管哪种方案都需要编译node Addon,安装环境,最好提前装好python环境:

cnpm install node-gyp -g

cnpm i -g --production windows-build-tools

  • 下面试试ffi-napi是否好使

在src目录下新建ffi-test.js

const ffi = require('ffi-napi');const adddd = new ffi.Library('./dllDir/testDLL.dll',{ 'Add':['int',['int','int']]})
function Add(a,b){ var res = adddd.Add(a,b) return res}export { Add}

在background.js中const win = new BrowserWindow创建BrowserWindow对象语句后面添加:

//导入import {Add} from './ffi-test'

//创建BrowserWindow对象语句后面添加setInterval(()=>{ let ss = Add(5,8) console.log(ss) win.webContents.send('main-process-messages',ss)},10*1000)

代码调用了我写的一个外部动态库testDLL.dll中的Add函数。

此时运行会弹出JavaScript错误:

Error: No native build was found for platform=win32 arch=x64 runtime=electron abi=85 uv=1 libc=glibc node=12.18.3 electron=11.2.1 webpack=true。

处理方法:

在根目录vue.config.js中添加:

这是拷贝静态文件用的。

因为这两个模块中包含原生 C代码,所以要在运行的时候再获取,而不是被webpack打包到bundle中。

现在开发模式下基本可以编译通过,打包构建会发生错误。需注意以下几个问题(可能出现):

Error: Dynamic Symbol Retrieval Error: Win32 error 127

方法对不上,js的方法c++没有定义,或c++接口未添加extern c。

Error: Dynamic Linking Error: Win32 error 193

dll 位数不对应,例如electron是32位的dll是64位的

Error: Dynamic Linking Error: Win32 error 126

dll存放位置不对,exe找不到dll。