electron 使用 node-ffi 调用 C++ 动态链接库(DLL)
一、为什么需要使用DLL
- 需要使用系统 API 操作或扩展应用程序;
- 需要调用第三方的接口API,特别是与硬件设备进行通信,而这些接口 API 基本上都是通过 C++ 动态链接库(DLL)实现的;
- 需要调用C++实现的一些复杂算法等。
二、node-ffi 是什么
node-ffi:Node.js Foreign Function Interface
node-ffi is a Node.js addon for loading and calling dynamic libraries using pure JavaScript. It can be used to create bindings to native libraries without writing any C++ code. It also simplifies the augmentation of node.js with C code as it takes care of handling the translation of types across JavaScript and C, which can add reams of boilerplate code to your otherwise simple C. See the example/factorial for an example of this use case.
WARNING: node-ffi assumes you know what you're doing. You can pretty easily create situations where you will segfault the interpreter and unless you've got C debugger skills, you probably won't know what's going on.
上面是 node-ffi 的介绍,英语不好,就不翻译了。
三、electron 使用 node-ffi
使用上一篇文章里的项目,在 package.json 的 dependencies 节点上加上node-ffi 依赖:
"dependencies": {
        "electron": "^1.6.11",
        "ffi": "2.2.0"
    }
然后安装缺失的 npm 包(参考之前的文章),注意,安装 ffi npm 包之前需要安装 python2.7,否则 ffi 会编译总是失败,导致安装不成功,具体安装参考:https://github.com/nodejs/node-gyp#installation。
安装完成后,在 app.js 文件第一行中添加如下代码:
const ffi = require('ffi')
然后运行程序,出现如下错误:

参考资料:https://github.com/electron/electron/blob/master/docs-translations/zh-CN/tutorial/using-native-node-modules.md,原来是需要把 ffi 重新编译为适合 electron的模块。
打开 nodejs 命令行窗口,先执行如下命令:
set python=python安装路径\python.exe
设置 python 的路径,切换到项目目录,然后执行如下命令:
"./node_modules/.bin/electron-rebuild" "./node_modules/ffi"

编译完成后,运行程序,漂亮的界面终于出现了。
四、使用 ffi 调用 Widows API 解决一个小缺陷
上篇文章中的仿 QQ 登录界面还有一个小问题,就是鼠标右键点击窗口的任意地方,都会弹出系统菜单:

现在使用 ffi 调用 user32.dll 中的 GetSystemMenu 函数来解决这个问题,首先新建一个 user32.js 文件,为了展示 ffi ,我多定义了几个API函数:
const ffi = require('ffi')
exports.User32 = ffi.Library('user32', {
    'GetWindowLongPtrW': ['int', ['int', 'int']],
    'SetWindowLongPtrW': ['int', ['int', 'int', 'long']],
    'GetSystemMenu': ['int', ['int', 'bool']],
    'DestroyWindow': ['bool', ['int']]
});
修改 app.js 文件,首先导入 user32.js:
const user32 = require('./app/scripts/user32').User32
然后修改如下内容:
win.once('ready-to-show', () => {
        let hwnd = win.getNativeWindowHandle() //获取窗口句柄。
        user32.GetSystemMenu(hwnd.readUInt32LE(0), true); //禁用系统菜单.
        win.show()
    })
再运行项目,系统菜单就消失的无影无踪了。
最后,所有代码都已经提交到了github:https://github.com/starts2000/ElectronQQLogin,欢迎获取。
electron 使用 node-ffi 调用 C++ 动态链接库(DLL)的更多相关文章
- wincc C脚本如何调用第三方动态链接库dll
		就Wincc本身脚本功能而言并不强大,但是wincc 脚本提供了第三方接口,如通用的Kernel32.dll,User32.dll,Gdi32.dll,大家如果对这些API接口感兴趣,可网上查找关于w ... 
- JAVA java调用C++动态链接库dll,有详细过程。VS2015+Eclipse以及失败解决方案
		一.新建Java工程,在Java类中声明一个native的方法 新建Java项目 在新建的项目中创建packet(包),并且在包下创建一个Class(类). 接下来,在该类中添加如下代码: ? 1 2 ... 
- Node.js调用C#代码
		在Node.js的项目中假如我们想去调用已经用C#写的dll库该怎么办呢?在这种情况下Edge.js是一个不错的选择,Edge.js是一款在GitHub上开源的技术,它允许Node.js和.NET c ... 
- Node调用C++(dll)
		最近开始搞毕设了,打算用自己拿手的js来搞,但是仿佛入坑了,Node还不是很熟.总之,兵来将挡,水来土掩嘛,带着问题学习才是最高效的. 折腾1:Node 调用 C++ 刚开始,虽然我老师把dll文件给 ... 
- 编译可供C#调用的C/C++动态链接库dll文件
		编译可供C#调用的C/C++动态链接库dll文件,C语言控制台应用程序,探索生成dll过程 由于项目需求,需要公司另一个团队提供相关算法支持,是用C语言编译好的dll库提供给我们进行调用. 但是拿到d ... 
- VS2010编写动态链接库DLL及单元测试用例,调用DLL测试正确性
		转自:http://blog.csdn.net/testcs_dn/article/details/27237509 本文将创建一个简单的动态链接库,并编写一个控制台应用程序使用该动态链接库,该动态链 ... 
- ASP.net/C#中如何调用动态链接库DLL
		动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows最重要的组成要素之一,打开Windows系统文件夹,你会发现文件夹中有很多DLL文 ... 
- VC++:创建,调用MFC动态链接库(扩展DLL)
		概述 DLL(Dynamic Linkable Library)动态链接库,Dll可以看作一种仓库,仓库中包含了可以直接使用的变量,函数或类. 仓库的发展史经历了"无库" ---& ... 
- BCB如何编写,调用动态链接库DLL
		一 编写动态链接库DLL DLL简称动态链接库,是Windows中程序的重要组成部分.想象一下,一个程序需要多人共同完成开发,怎么个共同法?这时我们就要考虑把程序分为好几个模块,团队每一个成员开发一个 ... 
随机推荐
- week07 13.3 NewsPipeline之 三News Deduper之 tf_idf 查重
			我们运行看结果 安装包sklearn 安装numpy 安装scipy 终于可以啦 我们把安装的包都写在文件里面吧 4行4列 轴对称 只需要看一半就可以 横着看 竖着看都行 数值越接近1 表示越相似 我 ... 
- 十六、Mediator 仲载者设计模式
			原理: 代码清单: Mediator public interface Mediator { void createColleagues(); void colleagueChanged(); } C ... 
- 网络请求Adapter添加数据
			一般在开发中我们都需要在listview中添加数据显示在界面上 1.首先我们会在布局中写一个listview <FrameLayout xmlns:android="http://sc ... 
- 拿来主义:treeview插件父子节点问题
			鄙人公司没有专门的前端,所以项目开发中都是前后端一起抡.最近用bootstrap用的比较频繁,发现bootstrap除了框架本身的样式组件外,还提供了多种插件供开发者选择.本篇博文讲的就是bootst ... 
- 七、eclipse添加离线约束,使不联网也能有一些代码的提示,例如dubbo
			eclipse添加离线约束,使不联网也能有一些代码的提示,例如dubbo 1.将dubbo.xsd文件放到一个无中文目录下 2.eclipse->windows->preferences- ... 
- apache提示make_sock?
			[root@localhost apache]# /etc/init.d/*_apache restart 停止 *_apache: [失败] 正在启动 *_apache:(98)Address al ... 
- LibreOJ #6014. 「网络流 24 题」最长 k 可重区间集
			#6014. 「网络流 24 题」最长 k 可重区间集 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 ... 
- 找不到phpize
			yum install php-devel 报错如下: 解决办法: yum install php71w-devel 
- boost asio 学习(五) 错误处理
			http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg=6 5. Erro ... 
- boost asio 学习(一)io_service的基础
			原文 http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio/ 编译环境 b ... 
