Categories: node js

ffi-napi - electron 调用 原生代码

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,可以唯一的标识一个方法。另外,你不需要写动态库的后缀名称,它会自动加给你,主要是不同系统动态库的后缀名称不一样。

full-stack-trip

Share
Published by
full-stack-trip

Recent Posts

Android 自定义 View 入门

说来惭愧,工作数年,连基本的自…

4 年 ago

retrofit 同时支持 xml 和 json

retrofit 解析 jso…

4 年 ago

mysql - 存储过程 从入门到放弃

最近有个报表的需求,于是乎用了…

4 年 ago

奶嘴战略 - 你不得不知道的扎心真相(一)

一句:英雄枯骨无人问,戏子家事…

4 年 ago

acme.sh 的简单使用

acme.sh 是纯 shel…

4 年 ago

wrk -更现代化的http压测工具

wrk 是一款更现代化的 ht…

4 年 ago