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}; } }}