Electron中调用dll

截止目前Electron的官方稳定版本已经更新到了28.1.1。我在创建Electron项目时用的28.0.0版本,后面在项目中有用到调用dll方法的需求,大致的实现就是将后端给的dll文件引入到项目中,安装ffi-napi依赖,然后进行使用。但是在ElectronV21+的时候,官方引入了V8内存隔离区,当再使用ffi-napi这个库的时候就会报错,用尽了一切办法,都未果(如果读者有解决办法可私聊)。最终还是将Electron版本降到了20.3.8。当然ffi-napi这个依赖库官方也没有及时进行维护更新,最近上一次更新已经是三年前了。

所以本篇教程是在Electron版本为20.3.8的情况下完成的,如果读者想找更高版本的教程,那可以不用读了。

一、准备阶段

你需要安装以下内容:

  1. python2
  2. npm i node-gyp
  3. npm i ffi-napi
  4. npm i -g --production windows-build-tools
  5. @electron/rebuild

如果在安装windows-build-tools时报错了,请根据报错提示信息找到对应文件夹的exe文件,手动进行安装。
在安装完@electron/rebuild之后,需要到node_modules/ffi-napi目录下 跑rebuild命令 重新编译一下。
至此,准备工作结束。

二、封装ffi-napi模块

注:调用封装好的Dll方法是在主进程中使用,通过渲染进程与主进程通信从而达到调用dll方法的效果。
新建ffi-core.js

const ffi = require('ffi-napi');
const path = require('path');

let binPath = path.join(__dirname, '../binary/core_x64.dll')

const bin = ffi.Library(binPath, {
    Client: ['string', ['string', 'string']]
})

module.exports = bin

另新建 api.js

const bin = require('./ffi-core')
const { Init, Login } = require('./core') // 此文件根据自己的业务编写

module.exports = {
    initApp: function() {
        return Init.Output(
            bin.Client(Init.Method, Init.Input('', ''))  // 调用dll方法主要在这一部分
        )
    },
    login: function({account, pwd}) {
        return Login.Output(
            bin.Client(Login.Method, Login.Input(account, pwd))
        )
    }
}

在preload.js中向渲染进程暴露对象:

const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('service', {
    login: (data) => ipcRenderer.invoke('login', data),
})

在主进程中监听调用api.js中暴露的接口:
main.js

const {ipcMain} = require('electron');
const api = require('./main/api');

ipcMain.handle('login', (_, data) => {
    return api.login(data)
})

接着,在渲染进程中使用preload.js暴露的服务:

const login = async () => {
	const res = await window.service.login({
	   account: 'root',
	   pwd: '123456789'
	 })
}

调用登录返回的结果