electron集成C++ dll 实践

游走的豚鼠君 2020-01-07

#1 背景

最近需要做桌面端项目,打算尝试使用 electron 来开发,开发之前需要调研一些可行性,最关键的一点是:集成公司的统一登录 sdk,登录的 sdk 只有 C++ sdk 才能实现单点登录,所以这里就放弃去集成 js 的 sdk。

#2 怎么集成C++ dll

Google全网,最终放弃addons编译那种,太过于复杂,剩下两种方式:
第一种:node-ffi
第二种:node-ffi-napi

#3 为啥放弃node-ffi-napi这种方式

坦白说,napi 这种方式安装啥的都很方便,调试登录的过程中,出现的一个问题让我放弃了这种,登录接口需要传入回调函数,napi 的callback有点鸡肋(也可能是我没有用好吧,从网上查阅了很多资料最终放弃了),登录成功回调会让 electron crash

#4 准备环境

明确一点,我们开发的是一个win32程序,x86的(32位)
所以各个版本需要对齐(electron的
安装 Python 设置环境变量(后面遇到问题也会触发去设置)
npm install -g node-gyp
npm install -g windows-build-tools
继续安装(#node-12 为了让ffi支持node 12):
"dependencies": {
    "ffi": "github:lxe/node-ffi#node-12",
    "ref": "github:lxe/ref#node-12",
    "ref-struct": "github:lxe/ref-struct#node-12",
    "iconv-lite": "^0.5.0"
  }

#5 版本对齐很重要

我集成的 dll 是32位的,那么我选择 安装的 electron 也是 32位 win32 平台,参考 这里

npm install --arch=ia32 --platform=win32 --save-dev

#6 为什么选择

我使用 node-ffi 集成 C++ dll,这个库目前支持到的 electron 就是 5.0 的版本,我是从最新的 7.x 退到 5.0 的版本才成功集成的。这期间琢磨了 1 天

#7 打包工具

这个没啥可说的,考虑到 更新 ,选择 electron-build 比较靠谱

npm install electron-builder --save-dev

#8 nodejs <==> C++ 参数如何传递

调用 C++ 的方法都会涉及到一些参数和回调函数的传递,nodejs 和 C++ 的通讯的消息格式显然需要一个桥梁来转换,这个桥梁就是 Buffer

#9 调用demo

const LID = ffi.Library("./LsfSdk.dll", {
        Init: ["int", ["string", "pointer", "pointer", "pointer"]],
        LoginByGroup: ["int", ["string", "pointer", "pointer", LoginOptionsPtr]]
      });

#10 demo 说明

1 LsfSdk.dll 就是我需要集成的 C++ 提供的登录 SDK
2 Init,LoginByGroup 是里面的方法

#11 类型 ref ref-struct ref-array 等

nodejs 和 C 的类型需要一个转换 ref 已经包含了大部分了,如果有结构体 需要 安装 ref-struct,如果还有 ref 不包括的,可以继续搜索 ref-其它的类型
可以参考 这里

#12 char* pointer 和 struct *

char* 对应 string
windows 句柄等 对应 pointer
结构体指针 需要 使用 ref-struct 在 js 里面创建 一个 struct,然后使用const LoginOptionsPtr = ref.refType(LoginOptions)  // LoginOptions 是一个struct

#13 可能出现 wchar* 或 tchar* 的乱码问题

坦白说,这个问题困扰我很久,因为 nodejs 默认的字符串编码就是 utf8 ,当我直接传字符串的时候(我们的登录 sdk 是可以定制一些参数,比如文本 按钮颜色等),参数类型是 wchar* 或 tchar*(这个是C++里面的一个定义),类型就是 wchar* ,实际上 对应到 nodejs 里面的类型是 utf-16。所以这里安装一个 iconv-lite 对字符串进行一次 encode 就行了

iconv.encode(str, "utf-16");

#14 结语

electron 的版本升级都伴随一些 break changes 所以一开始选择好版本,做好可行性的验证很重要
如果需要集成 dll ,那么现阶段 electron 选择 5.0.13 比较合适,高版本会有很多问题无法解决。也许 node-ffi 后面会升级,能使用更新版本的 electron。
总的来说:electron 值得一试~,希望我的文章对你有帮助

原文发布在 :https://zhangxuefei.site/p/2653

相关推荐