一、为什么需要使用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. Python教程(2.7)——条件分支

    像其它语言一样,Python也有条件分支. 例如,输入用户年龄,可能需要判断是否成年,并做出不同反应.这就需要用到条件分支. if条件分支 if条件分支的一般格式如下: if condition: s ...

  2. 堆结构的优秀实现类----PriorityQueue优先队列

    之前的文章中,我们有介绍过动态数组ArrayList,双向队列LinkedList,键值对集合HashMap,树集TreeMap.他们都各自有各自的优点,ArrayList动态扩容,数组实现查询非常快 ...

  3. 构建自己的PHP框架--构建模版引擎(2)

    自从来到新公司就一直很忙,最近这段时间终于稍微闲了一点,赶紧接着写这个系列,感觉再不写就烂尾了. 之前我们说到,拿到{{ $name }}这样一段内容时,我们只需要将它转化成<?php echo ...

  4. html5shiv.min.js 和 respond.min.js 作用(bootstrap做IE低版本兼容时需要用到这两个插件)

    1. html5shiv.min.js解决ie9以下浏览器对html5新增标签的不识别,并导致CSS不起作用的问题. respond.min.js让不支持css3 Media Query的浏览器包括I ...

  5. JQuery树形目录插件Dynatree

    最近做网页需要做一个树形目录功能.找了一下发现有很多JQuery插件都可以实现这个功能.选了一个自己觉得最满意的插件Dynatree做个学习笔记. 可以把静态的html转成树形目录,还可以动态创建添加 ...

  6. eclipse tomcat add时提示The Tomcat server configuration at \Servers\Tomcat v6.0 Server at localhost-

    原因为左侧项目中把对于网络应用的servers项目给关闭或删除了,导致相应的localhost-config无法定位,所以才发生的错误. 解决办法:删除servers下的tomcat 重新添加serv ...

  7. Java NIO 学习笔记五 缓冲区补充

    1.缓冲区分配 方法   以 ByteBuffer 为例 (1)使用静态方法 ByteBuffer buffer = ByteBuffer.allocate( 500 ); allocate() 方法 ...

  8. 原生js二级联动

    今天说的这个是原生js的二级联动,在空白页面里动态添加并作出相对应的效果. 1 //创建两个下拉列表 select标签 是下拉列表 var sel = document.createElement(& ...

  9. 如何在前端模版引擎开发中避免使用eval函数

    前段时间,想着自己写一个简单的模版引擎,便于自己平时开发demo时使用.于是根据自己对模版引擎的理解,定义自己的模版格式,然后,根据自己定义的格式,编写处理函数,将模版标签中的字符串,解析成可执行的字 ...

  10. java编码详解

    举个例子 我们在开发过程中,特别是多种编码格式并存的情况下,很容易遇到乱码问题. 假如有一个GBK编码java文件,然后再使用-Dfile.encoding=GBK参数,写入的文件中哪些是乱码呢.那如 ...