游走的豚鼠君 2020-01-07
最近需要做桌面端项目,打算尝试使用 electron 来开发,开发之前需要调研一些可行性,最关键的一点是:集成公司的统一登录 sdk,登录的 sdk 只有 C++ sdk 才能实现单点登录,所以这里就放弃去集成 js 的 sdk。
Google全网,最终放弃addons编译那种,太过于复杂,剩下两种方式:
第一种:node-ffi
第二种:node-ffi-napi
坦白说,napi 这种方式安装啥的都很方便,调试登录的过程中,出现的一个问题让我放弃了这种,登录接口需要传入回调函数,napi 的callback有点鸡肋(也可能是我没有用好吧,从网上查阅了很多资料最终放弃了),登录成功回调会让 electron crash
明确一点,我们开发的是一个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" }
我集成的 dll 是32位的,那么我选择 安装的 electron 也是 32位 win32 平台,参考 这里
npm install --arch=ia32 --platform=win32 --save-dev
我使用 node-ffi 集成 C++ dll,这个库目前支持到的 electron 就是 5.0 的版本,我是从最新的 7.x 退到 5.0 的版本才成功集成的。这期间琢磨了 1 天
这个没啥可说的,考虑到 更新 ,选择 electron-build 比较靠谱
npm install electron-builder --save-dev
调用 C++ 的方法都会涉及到一些参数和回调函数的传递,nodejs 和 C++ 的通讯的消息格式显然需要一个桥梁来转换,这个桥梁就是 Buffer
const LID = ffi.Library("./LsfSdk.dll", { Init: ["int", ["string", "pointer", "pointer", "pointer"]], LoginByGroup: ["int", ["string", "pointer", "pointer", LoginOptionsPtr]] });
1 LsfSdk.dll 就是我需要集成的 C++ 提供的登录 SDK
2 Init,LoginByGroup 是里面的方法
nodejs 和 C 的类型需要一个转换 ref 已经包含了大部分了,如果有结构体 需要 安装 ref-struct,如果还有 ref 不包括的,可以继续搜索 ref-其它的类型
可以参考 这里
char* 对应 string windows 句柄等 对应 pointer 结构体指针 需要 使用 ref-struct 在 js 里面创建 一个 struct,然后使用const LoginOptionsPtr = ref.refType(LoginOptions) // LoginOptions 是一个struct
坦白说,这个问题困扰我很久,因为 nodejs 默认的字符串编码就是 utf8 ,当我直接传字符串的时候(我们的登录 sdk 是可以定制一些参数,比如文本 按钮颜色等),参数类型是 wchar* 或 tchar*(这个是C++里面的一个定义),类型就是 wchar* ,实际上 对应到 nodejs 里面的类型是 utf-16。所以这里安装一个 iconv-lite 对字符串进行一次 encode 就行了
iconv.encode(str, "utf-16");
electron 的版本升级都伴随一些 break changes 所以一开始选择好版本,做好可行性的验证很重要
如果需要集成 dll ,那么现阶段 electron 选择 5.0.13 比较合适,高版本会有很多问题无法解决。也许 node-ffi 后面会升级,能使用更新版本的 electron。
总的来说:electron 值得一试~,希望我的文章对你有帮助