Java 调用dll过程当中 JNI的方式,存在隐患,dll常常挂掉,为此采用nodejs 调用dll进行封装
1.Win7 sp1 (x64操做系统)javascript
- Win7系统必定要是sp1的,没有sp1补丁自行到官网下载,sp1补丁(最好本身有系统盘,亲测安装补丁过程比安装系统还慢)
- 若是这个补丁没有更新是装不上Visual Studio 2013的,仍是乖乖的用这个版本吧。 (我的使用版本经历,让人泪奔 vs2015 —— vs2017 —— vs2013)
2.Visual Studio 2013html
- 提供基础的编译环境,nodejs modules在从新编译的时候须要依赖它
- 上面已经说了,老老实实安装吧!!!
3.Python 2.7.6java
- 提供基础的编译环境,nodejs modules在从新编译的时候须要依赖它
- 下载地址 : https://www.python.org/ftp/py...
4.nodeJS 0.12.3node
- 通常dll文件都是32位的,ffi调用时须要使用32位版本的nodejs
- 下载地址:https://nodejs.org/download/r... 文件是msi格式,直接安装便可,环境变量自动配好不用管。
5.nwjs 0.12.3python
- 为保证程序能够在xp下使用不是使用过高的版本我选择了0.12.3版本
- 下载地址:http://dl.nwjs.io/v0.12.3/nwj...
1.打开DOS界面,安装nw-gyp执行下面的命令:
npm install nw-gyp -g
2.设置vs版本:
npm config set msvs_version 2013 --global (2013是visual studio的版本,你也能够尝试其余版本,我是放弃了)
1.新建一个项目文件夹,建立index.html和package.json文件:
(测试是用的windows系统里的消息窗口dll文件)c++
<html lang="en">
<head>web<meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>nwjs call DLL</title> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"></head>
<body>
<script type="text/javascript">npmvar FFI = require('ffi'); function TEXT(text){ return new Buffer(text, 'ucs2').toString('binary'); } var user32 = new FFI.Library('user32', { 'MessageBoxW': [ 'int32', [ 'int32', 'string', 'string', 'int32' ] ] }); var OK_or_Cancel = user32.MessageBoxW( 0, TEXT('I am Node.JS!'), TEXT('Hello, World!'), 1 ); console.log(OK_or_Cancel);</script>
</body>
</html>json
package.json
{
"name": "test",
"version": "1.0.1",
"main": "index.html",
"webkit":{
windows"plugin" : true<br>}
}注意package.json文件里须要添加webkit属性来讲明你须要调用第三方包。
2.DOS界面下进入项目文件夹,安装ffi和ref:
npm install ffi
npm install ref
3.编译ffi和ref模块,由于ffi中包含ref因此先编译ref再编译ffi,依次的命令以下:
进入'项目目录node_modulesffinode_modulesref',执行nw-gyp rebuild --target=0.12.3
(0.12.3是你的nwjs版本,若是不是这个版本改成你本身的便可)
进入'项目目录node_modulesffi',执行nw-gyp rebuild --target=0.12.3
4.最后在你的项目文件夹下将全部文件打包为zip格式,将zip文件拖进node-webkit目录下的nw.exe文件上执行便可。
5.看到界面上弹出“I am Node.JS!”说明成功了!参考:https://cnodejs.org/topic/541...
提示:
1.因为ffi模块是为C语言的dll包服务的,因此在编写的dll的C++源代码时必需要有 extern “C” 来修饰。例如在你的c++代码里须要这样声明函数才能有效(在.h文件中声明时使用):
extern "C" DLLSERVER_API int sumInDll(int n1, int n2);
2.ffi在使用时须要匹配对应的环境,若是是32位dll文件,那么在安装nodeJS,python和nwjs都须要用对应的32位版本;若是是64位dll文件,则对应的软件都须要是64位的;
3.ffi在用的时候仍是挺方便的,只要环境匹配对就能够。惟一的麻烦是它须要对源dll代码声明时进行修改,这个就不如addon一劳永逸了。因此若是引用的dll文件比较多,或者是引入第三方dll文件,ffi的方法就不可取。
一、winxp 系统下dll错误
nodejs的ffi库是一个很是好用的调用dll的库,尤为是在使用nwjs进行桌面应用开发的时候。
安装、编译、使用ffi库的方法比较简单,网上也有不少教程,可是当咱们在win7或者更高的Windows系统中编译好了ffi模块,开发好了应用后会发如今Windows XP上没法require咱们的ffi,及时将编译好的ffi_bindings.node单独require也没法使用,require的时候会出现“Error: The specified procedure could not be found”的错误。
通过几天的研究,终于找到了解决方案。在可以正常编译和引用ffi的Windows系统上,进入ffi文件夹中的src文件夹,找到文件“win32-dlfcn.cc”,并将里面的地96行和第99行的两行代码(我是用的ffi版本为2.2.0,其余版本尚未肯定是否是这两行),对应的代码应该是:errorMode = GetErrorMode();
SetErrorMode(errorMode | SEM_FAILCRITICALERRORS);
将这两行代码注释掉,而后在从命令行进入到ffi根目录,执行“node-gyp rebuild”命令(或者“nw-gyp rebuild”命令,若是想要在nwjs中使用),编译出来的ffi库就能够在Windows XP上正常使用了。
参考文章:https://blog.csdn.net/wuya199...
二、nodejs 读取中文乱码问题 (iconv-lite)
var ref = require("ref");
var ffi = require("ffi");
var iconv = require('iconv-lite');
var DLL = new ffi.Library('sample.dll', {
'readData': ['int', ['string', 'string']],
'sendMsg': ['string', ['string', 'string']]
});module.exports = {
sendMsg: function(sendMsg){ var maxRTNNameLength = 4096; var rtnRef = new Buffer(maxRTNNameLength); console.log("send:",sendMsg); var rtn = DLL.sendMsg(sendMsg, rtnRef); var as_data = iconv.decode(rtnRef, 'GBK');//解码成utf8. var userbuffer = iconv.encode(as_data, 'gbk');//utf8数据编码成gbk var as_data = iconv.decode(rtnRef, 'GBK');//解码成utf8. return as_data; }, readData:function(){ var maxIdCardLength = 19; var idCardRef = new Buffer(maxIdCardLength); var maxNameLength = 31; var nameRef = new Buffer(maxNameLength); if (DLL.readData(idCardRef, nameRef) == 0) { var name = ref.readCString(nameRef, 0); var card = ref.readCString(idCardRef, 1); return {name: name, card: card}; } }}