一、为什么需要使用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)的更多相关文章

  1. electron 使用 node-ffi 调用 C++ 动态链接库(DLL)

    一.为什么需要使用DLL 需要使用系统 API 操作或扩展应用程序: 需要调用第三方的接口API,特别是与硬件设备进行通信,而这些接口 API 基本上都是通过 C++ 动态链接库(DLL)实现的: 需 ...

  2. Node调用C++(dll)

    最近开始搞毕设了,打算用自己拿手的js来搞,但是仿佛入坑了,Node还不是很熟.总之,兵来将挡,水来土掩嘛,带着问题学习才是最高效的. 折腾1:Node 调用 C++ 刚开始,虽然我老师把dll文件给 ...

  3. 编译可供C#调用的C/C++动态链接库dll文件

    编译可供C#调用的C/C++动态链接库dll文件,C语言控制台应用程序,探索生成dll过程 由于项目需求,需要公司另一个团队提供相关算法支持,是用C语言编译好的dll库提供给我们进行调用. 但是拿到d ...

  4. VC++动态链接库(DLL)编程深入浅出(zz)

    VC++动态链接库(DLL)编程深入浅出(zz) 1.概论 先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用 ...

  5. VS2010编写动态链接库DLL及单元测试用例,调用DLL测试正确性

    转自:http://blog.csdn.net/testcs_dn/article/details/27237509 本文将创建一个简单的动态链接库,并编写一个控制台应用程序使用该动态链接库,该动态链 ...

  6. 无法加载 DLL“rasapi32.dll”: 动态链接库(DLL)初始化例程失败。

    无法加载 DLL“rasapi32.dll”: 动态链接库(DLL)初始化例程失败. 在Asp.Net项目中使用WebClient或HttpWebRequest时出现以上错误 解决方案:把以下代码放在 ...

  7. delphi 2010 动态链接库DLL断点调试

    DELPHI 2010 动态链接库DLL断点调试 马根峰 (广东联合电子服务股份有限公司,广州 510300) 摘要:本文详细介绍了Delphi 2010中的动态链接库DLL断点调试技术 关键词:DE ...

  8. 动态链接库 DLL

    动态链接库DLL 不使用时不会有任何作用,只有在其他模块调用动态链接库中的函数时,它才发挥作用. 一.静态库与动态库 1.静态库 函数和数据被编译进一个二进制文件(.LIB),编译时,会将其组合起来创 ...

  9. MinGW gcc 生成动态链接库 dll 的一些问题汇总 (补充)

    我以前写过一个小短文,介绍MinGW gcc 生成动态链接库 dll 的一些问题.当时写的并不全面.近期又遇到写新的问题.这里记录一下,做个补充. 通常情况下,dll 中的函数假设採用 _stdcal ...

  10. 动态链接库dll,静态链接库lib, 导入库lib

    转载地址:http://www.cnblogs.com/chio/archive/2008/08/05/1261296.html 目前以lib后缀的库有两种,一种为静态链接库(Static Libar ...

随机推荐

  1. QUICK-AP + BETTERCAP 替换局域网内其他用户的下载文件为自定义文件

    环境需求 :kali系统 , .0版本 :quick-ap :bettercap :bettercap-proxy-modules :...... 主要环境搭建 目的:替换局域网用户的下载文件,变为我 ...

  2. Maximum Subarray Sum

    Maximum Subarray Sum 题意 给你一个大小为N的数组和另外一个整数M.你的目标是找到每个子数组的和对M取余数的最大值.子数组是指原数组的任意连续元素的子集. 分析 参考 求出前缀和, ...

  3. 一步一步实现android studio代码上传到github。

    本文只注重代码上传能成功就好,不解释什么是git什么事github,git有什么优势. 1,先创建一个android应用, 第二步:创建github账户 和 安装git.网上的文章多如牛毛.唯一要说的 ...

  4. HashMap集合

    HashMap集合特点(用法与特点类似于HashSet集合): 1.无序,不允许重复(无序指元素顺序与添加顺序不一致): 2.底层数据结构是哈希表 3.HashMap内部对"键"用 ...

  5. 关于ASP.NET WebForm与ASP.NET MVC的比较

      WebForm的理解 1. WebForm概念 ASP.NETWebform提供了一个类似于Winform的事件响应GUI模型(event-drivenGUI),隐藏了HTTP.HTML.Java ...

  6. Android开发的过去、现在和将来

    现如今,拥有着 80% 的市场份额的 Android 是最主流的手机操作系统.它运行在无数的智能手机.平板以及其他各种各样的设备上.仅凭这一点,我们是否可以认为  Android 编程是简单而轻松的呢 ...

  7. IntelliJ IDEA 2017.1.4 x64配置说明

    只是为了研究下idea这款编译器怎么使用.开门见山,说下如何配置这款编译器,不配置也能用,但是强迫症表示不服.下面直入正题: 下载与安装就不说了,除了更改安装目录外,没啥注意的地方,建议下载idea去 ...

  8. sock

    头和尾基本用来做校验, 不是拿来做边界的. 头+类型+长度+数据+尾, 这种结构就可以. 拆包就是: 检验头, 然后拆出类型+长度, 然后根据长度拆数据, 然后检验尾巴.

  9. cpp(第九章)

    1.静态外部,不在任何函数内定义.静态内部,不在任何函数内,使用关键字static.静态无连接性,在代码块中,使用关键字static. 2.静态变量会自动零初始化. 3.单定义规则,在每个使用外部变量 ...

  10. 调试JDK源码时,不能查看变量的值

    前几天本来想以debug模式看一下JDK的源码,进入调试模式时才发现,根本看不到方法里面变量值的情况.为什么呢?JDK现在的版本中,编译过后,去除了里面的调试信息.解决办法是,编译那些类,使其带有调试 ...