electron 很不错,可以实现跨平台应用的开发,但是如果需要跟硬件交互就显得欠缺了,好在 electron 实际上是 node js + html + css,而 nodejs 想要调用本地代码还是可以实现的。我也是基于这个想法去做的,但是遇到了一堆的问题。
实际上,electron 需要较高版本的 nodejs 而 ffi 却不支持高版本 nodejs,笔者这里是 nodejs 12 这个版本。如果使用 ffi 也可以,但是页面显示不出来,之后换用 nodejs8,但是 electron 用不了,毕竟 nodejs8 已经快要不维护了。
之后使用了,ffi-napi ,其使用方法与 ffi 一样,但是兼容 nodejs 12,下面是我个人写的一段例子。
hello.c
#include <stdio.h> int cal(int i,int j) { j= i+j; return j; }
然后编译这个文件:gcc hello.c -fPIC -shared -o hello.so 此时会生成一个 hello.so 文件。将 hello.so 文件复制到 Electron 项目的某个目录,具体你来定。
test.vue
<script> const ffi = require('ffi-napi') const path = require('path') export default { name: 'Test', created() { const ffiPath = path.resolve(__dirname, '../../../dll/hello') const testLib = ffi.Library(ffiPath, { 'cal': ['int', ['int', 'int']] }) console.log('199 + 201 = ', testLib.cal(199, 201)) } }
这是 vue 源码,编译后运行,控制台会输出:199 + 201 = 400 的信息,这里虽然只有几行代码,却完全可以说明问题,核心代码如下:
created() { const ffiPath = path.resolve(__dirname, '../../../dll/show') const testLib = ffi.Library(ffiPath, { 'cal': ['int', ['int', 'int']] }) console.log('199 + 201 = ', testLib.cal(199, 201)) }
其中,最重要的代码是:'cal': ['int', ['int', 'int']],没错,其余代码都很好理解的。这里 cal 代表 native 方法的函数名,后面的 ['int', ['int', 'int']] 代表这个函数的一些参数,其中,第一个 int 是返回值,返回值只有一个类型,所以它并不是一个数组,而后面的 ['int', 'int'] 则代表入参,入参可能有多个,所以是个数组,这点也很好理解。
我们发现,这个调用方式和 ffi 是完全一样的,核心部分就是:'cal': ['int', ['int', 'int']] 这个表达式,它类似于 jni,可以唯一的标识一个方法。另外,你不需要写动态库的后缀名称,它会自动加给你,主要是不同系统动态库的后缀名称不一样。