不懂electron-vue的前端小白,如何实现与c++多线程交互
前言:
哈喽,掘友们,大家好呀!最近在业余的时间里,尝试跟朋友一起做了一款客户端产品,小编负责前端开发设计,后台逻辑呢是与c++和python交互。这是小编从未接触过的领域,从一开始的调研,到测试实现,真的是废了好大的功夫,可以说是煞费苦心。不过,庆幸的是,自己没有接触到的领域,可以实践在其中去学习,去了解这一系列的知识,当然,学到就是赚到。
开始调研
调研目的: 实现 Electron+vue 桌面应用开发与 C++ 交互通信,调用 C++ 代码 调研方法:通过 Node.js 插件 node-ffi-napi 调用 C++ 编写的Dll动态库,实现调用 C++ 代码
开发版本
- node v14.15.1
- vue v2.6.14
- electron v13.6.9
- node-gyp v9.3.1
- ffi-napi v4.0.3
上边是小编开发过程中使用到的依赖包以及版本号
环境准备
搭建环境,安装node-gyp、windows-build-tools
- 全局安装 node-gyp
npm install node-gyp -g
- 全局安装 windows-build-tools
npm install windows-build-tools -g
注意安装 windows-build-tools 时 python 版本必须为 2.7
使用ffi-napi
- 进入项目目录,安装ffi-napi
npm install ffi-napi --save
- 封装 C++ 方法文件
新建 callC.js 文件,放在 src 的 utils 目录下
引入 ffi-napi,path 模块,加载 C 方法,并导出
// 引入模块
const ffi = require('ffi-napi')
const path = require('path')
// 通过 ffi.Library 加载 dll 文件 加载 C++ 方法
const Dll = ffi.Library(path.resolve('resources/dll/MyDLL.dll'), {
Add: ['float', ['float', 'float']],
Hello: ['string', []],
StrLength: ['int', ['string']]
})
// 导出Dll状态库
export default Dll;
- 在 Electron + vue 中使用 C 方法
再使用组件中引入封装的文件
// 引入封装的callC文件
import Dll from '../../utils/callC'
mounted() {
console.log('fii.Library Hello result:', Dll.Hello())
console.log('fii.Library Add result:', Dll.Add(1, 2))
console.log('fii.Library Add result:', Dll.StrLength('hello world'))
}
调用 C 成功!
这个时候我们的dll代码已经调用成功了,但是如果c++中要求有回调函数,持续返回信息给我们,这时候就需要多线程,否则就会导致项目进程阻塞,页面卡死,无法使用。
web worker 多线程交互
使用多线程的目的
开发 electron + vue 桌面系统时, 使用 ffi-napi 调用 C++,实现交互。但是 C++ 代码如果进行循环式回调,会导致页面卡死,是因为JavaScript是单线程应用。也就是说,所有的任务都只能在一个线程上进行,如果要进行下一步,就只能等前边的任务执行完毕,才可以执行到下一步,如果计算量特别大,又或者说C++的回调函数一直在进行中,那么我们接下来的任务就无法进行,就会导致页面卡死、无法操作。
什么是web worker ?
Web worker 是为web 内容在后台线程中提供的一种简单的方法。线程可以执行任务而不干扰用户操作界面。创建web worker 可以将消息发送到创建它的JavaScript代码,通过消息发布到该代码指定的时间处理程序中,从而实现异步多线程调用函数。
如何在 vue + element 中使用 web worker 多线程开发
- 设置 Electron 的 webPreferences 中的 nodeIntegrationInWorker 选项设置为 true
const win = new BrowserWindow({
webPreferences: {
nodeIntegrationInWorker: true
}
})
- 安装 worker-loader
npm i worker-loader
- 编写 子线程 worker.js 文件
onmessage = function (e) {
console.log(e);
// 此处的e就是主线程通过postMessage 传递过来的数据
// 在此处进行数据分析,数据操作
postMessage(str); // 向主线程传递信息
}
- 在项目目录中 引入worker.js文件 ./worker.js是文件路径信息,引入直接写在 worker-loader! 后边
import Worker from 'worker-loader!./worker.js'
- 在 vue 中使用
methods:{
WorkerOne() {
// 新建一个线程
worker= new Worker()
// 线程之间通过postMessage进行通信
worker.postMessage(0)
// 监听message事件
worker.addEventListener('message', (e) => {
// 关闭线程
console.log('1------' + e.data);
})
worker.terminate() // 立刻终止一个运行中的 worker 终止线程
},
}
mounted() {
this.WorkerOne()
}
关于如何生成共享 worker, 官方文档给出了详细的介绍和说明。 developer.mozilla.org/zh-CN/docs/…
结尾
项目目前还在进行中,小编也是在不断地学习,electron官方文档中也是有很多的api,随后项目结束后我也会更新下文,关于我如何从头搭建electron—vue的项目,如何实现与c++、与python交互也会与大家分享。总而言之,学习永无止境,要试着向自己从未接触到的领域学习,这样会更直观的看到自己的不足,要学习的方向。
转载自:https://juejin.cn/post/7231057317332467767