欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Nodejs調(diào)用Dll模塊的方法

 更新時間:2018年09月17日 16:36:19   作者:蘇格團隊  
這篇文章主要介紹了Nodejs調(diào)用Dll模塊的方法,在文中給大家提到了nodejs通過ffi調(diào)用dll模塊的代碼,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下

公司項目采用Electron(electronjs.org/ )開發(fā)pc應(yīng)用,會涉及到與底層硬件設(shè)備的通信,而sdk封裝 基本上都是通過 C++ 動態(tài)鏈接庫dll實現(xiàn)的。

有兩種方案可供選擇:

  • 方案一: 使用node-ffi
  • 方案二: 使用C++編寫一個node addon,通過LoadLibrary調(diào)用dll

以上兩種方案都可以解決dll調(diào)用問題,方案選型要個人對C++ 的掌握程度,如果熟悉C++開發(fā),可以直接選擇方案二最方便。如果完全不了解C++,那么只能采用方案一。

由于筆主不太懂C++,最終選擇第一種方案。

二、什么是node-ffi?

www.npmjs.com/package/ffi

node-ffi是使用純JavaScript加載和調(diào)用動態(tài)庫的node addon,它可以用來在不寫任何C++代碼的情況下調(diào)用動態(tài)鏈接庫的API 接口。

ffi究竟干了什么?其實它本質(zhì)上還是一個編譯后的Node addon,node_modules/ffi/build/Release/ffi_bindings.node, ffi_bindings.node就是一個addon ffi充當了nodejs和dll之間的橋梁。

下面是一個簡單的加載dll的demo實例:

var ffi = require('ffi');
var libpath = path.join(_dirname, '/test.dll');
var testLib = ffi.Library(libpath, {
 'start': ['bool', ['bool']]
});
testLib.start(true); // true

三、安裝node-ffi

npm install ffi

如果本地沒有安裝編譯node addon的環(huán)境會報錯,如下圖所示

無論是使用ffi,還是直接寫node addon,都缺少不了編譯node Addon這個步驟,要編譯node addon,有兩種方法:

1、node-gyp( www.npmjs.com/package/nod … )。

npm install node-gyp

具體安裝參考:github.com/nodejs/node…

總結(jié)來說需要以下四點:

python 2.7-3.0版本之間 (推薦裝v2.7,v3.x.x是不支持的)

NET Framework 4.5.1

Visual C++編譯工具 (在windows中是不需要安裝VS,如果自己安裝例如VS2015,導致編譯報錯error MSB4132: The tools version "2.0" is unrecognized. Available tools versions are "4.0".這個問題,說明沒有裝好編譯器,又或者編譯器沒有被正確地識別, node-gyp的文檔建議使用npm config set msvs_version 2015, 但是有些機器即使這樣設(shè)置了也無效,需要手動設(shè)置msvs_version, 應(yīng)該這樣寫: node-gyp rebuild --msvs_version=2015。如果因為安裝了VS2015導致無法正常編譯,可直接恢復到安裝VS之前的還原點)
環(huán)境變量配置。(注:python安裝位置需要添加到環(huán)境變量)

2、electron-rebuild( www.npmjs.com/package/ele… )

如果采用electron開發(fā)應(yīng)用程序,electron同樣也支持node原生模塊,但由于和官方的node 相比使用了不同的 V8 引擎,如果你想編譯原生模塊,則需要手動設(shè)置electron的headers的位置。

electron-rebuild為多個版本的node和electron提供了一種簡單發(fā)布預編譯二進制原生模塊的方法。 它可以重建electron模塊,識別當前electron版本,幫你自動完成了下載 headers、編譯原生模塊等步驟。 一個下載 electron-rebuild 并重新編譯的例子:

npm install --save-dev electron-rebuild
# 每次運行"npm install"時,也運行這條命令
./node_modules/.bin/electron-rebuild
# 在windows下如果上述命令遇到了問題,嘗試這個:
.\node_modules\.bin\electron-rebuild.cmd

詳情請看 electronjs.org/docs/tutori…

這里需要注意nodejs版本問題,nodejs平臺必須跟dll保持一致,同樣是32位或者64位,如果兩者不一致,會導致調(diào)用dll失敗。

成功安裝ffi模塊之后,就可以開始我們下面的ffi調(diào)用dll的實例應(yīng)用。

四、應(yīng)用舉例

在開發(fā)需求中,需要調(diào)用基于C++編寫的TCP數(shù)據(jù)轉(zhuǎn)發(fā)服務(wù)的SDK。

首先我們來看一下dll頭文件接口聲明的代碼如下:

#ifndef JS_CONNECTION_SDK
#define JS_CONNECTION_SDK
#ifdef JS_SDK
#define C_EXPORT __declspec(dllexport)
#else
#define C_EXPORT __declspec(dllimport)
#endif
extern "C"
{
  typedef void(*ReceiveCallback) (int cmd, int seq, const char *data);
  /*設(shè)置讀取數(shù)據(jù)回調(diào)*/
  C_EXPORT void _cdecl SetReceiveCallback(ReceiveCallback callback);
  /*
  *設(shè)置option
  */
  C_EXPORT void _cdecl SetOption(
    const char* appKey, 
    const char* tk,
    int lc, 
    int rm
  );
  /*
  *創(chuàng)建連接
  */
  C_EXPORT bool _cdecl CreateConnection();
  /*發(fā)送數(shù)據(jù)*/
  C_EXPORT bool _cdecl SendData(int cmd, int seq, const char *data, unsigned int len);
  /*釋放連接*/
  C_EXPORT void _cdecl ReleaseConnection();
}
#endif

ffi調(diào)用dll模塊封裝,代碼如下:

try {
 const ffi = require('ffi');
 const path = require('path');
 const Buffer = require('buffer').Buffer;
 const libpath = path.join(APP_PATH, '..', '..', '/testSDK.dll');
 
 const sdkLib = ffi.Library(libpath, {
 'CreateConnection': ['bool', []],
 'SendData': ['bool', ['int', 'int', 'string', 'int']],
 'ReleaseConnection': ['void', []],
 'SetOption': ['void', ['string', 'string', 'int', 'int']],
 'SetReceiveCallback': ['void', ['pointer']]
 });
 
 module.exports = {
 createConnection: function(){
  sdkLib.CreateConnection();
 },
 setReceiveCallback(cb) {
  global.setReceiveCallback = ffi.Callback('void', ['int', 'int', 'string'], function(cmd, seq, data){
  cb && cb(cmd, seq, data && JSON.parse(data));
  });
  sdkLib.SetReceiveCallback(global.setReceiveCallback);
 },
 sendData: function(cmd, seq, data){
  data = JSON.stringify(data);
  sdkLib.SendData(cmd, seq, data, data.replace(/[^\x00-\xff]/g, '000').length, 0);
 },
 releaseConnection: function(){
  sdkLib.ReleaseConnection();
 },
 setOption: function (option) {
  sdkLib.SetOption(
  option.appKey,
  option.tk,
  option.lc,
  option.rm
  );
 }
 } 
} catch (error) {
 log.info(error);
}

第一步:通過ffi注冊dll接口

const sdkLib = ffi.Library(libpath, {
 'CreateConnection': ['bool', []],
 'SendData': ['bool', ['int', 'int', 'string', 'int']],
 'ReleaseConnection': ['void', []],
 'SetOption': ['void', ['string', 'string', 'int', 'int']],
 'SetReceiveCallback': ['void', ['pointer']]
 }); 

ffi.Library方法,第一個參數(shù)傳入dll路徑,第二參數(shù)JSON對象配置相關(guān)接口。

key對應(yīng)dll頭文件中輸出的接口,例如C_EXPORT bool _cdecl CreateConnection();

value array配置參數(shù)類型,array[0]注冊接口函數(shù)返回值類型,array[1]注冊接口函數(shù)傳入形參類型。

1、基礎(chǔ)參數(shù)類型bool, char, short, int, long等。

2、指針類型,需要引入ref模塊,如下:

var ref = require('ref');
var intPointer = ref.refType('char');
var doublePointer = ref.refType('short');
var charPointer = ref.refType('int');
var stringPointer = ref.refType('long');
var boolPointer = ref.refType('bool');

3、回調(diào)函數(shù)指針pointer,可以通過ffi.Callback創(chuàng)建,如下:

global.setReceiveCallback = ffi.Callback('void', ['int', 'int', 'string'], function(cmd, seq, data){
 cb && cb(cmd, seq, data && JSON.parse(data));
 });
sdkLib.SetReceiveCallback(global.setReceiveCallback);

回調(diào)函數(shù)參數(shù)類型配置與dll接口參數(shù)類型配置相同,這里就不多說。

這里需要注意一點,回調(diào)函數(shù)可能會被JavaScript垃圾自動回收機制回收,所以我這里是把回調(diào)函數(shù)掛載到全局對象global上。

第二步:接口調(diào)用

通過ffi.Library(libpath, {...})注冊接口,可以直通過返回的sdkLib對象調(diào)用對接的接口。例如:

var bool = sdkLib.CreateConnection();
console.log(bool); // true or false;
var cmd = 0, seq = 0, data = {...};
var dataStr = JSON.stringify(data);
// JavaScript中文字符長度在C++中長度計算要*3
sdkLib.SendData(cmd, seq, data, data.replace(/[^\x00-\xff]/g, '000').length);
global.setReceiveCallback = ffi.Callback('void', ['int', 'int', 'string'], function(cmd, seq, data){
 cb(cmd, seq, data && JSON.parse(data));
});
sdkLib.SetReceiveCallback(global.setReceiveCallback);

補充:下面看下NodeJS通過ffi調(diào)用DLL

第一步建立一個dll, 提供方法如下

int WINAPI CAM_Open(char *pIn, char* pOut);

第二步安裝ffi (前提已安裝python2.x環(huán)境)

npm install --save ffi

第三步創(chuàng)建測試文件

var ffi = require("ffi")
var DLL = ffi.Library('FaceRecognition.dll', {
  'CAM_Open' : ['int', ['string', 'string']]
});
var result = DLL.CAM_Open("", "");
console.log(result)

參考資料

https://github.com/node-ffi/node-ffi

總結(jié)

以上所述是小編給大家介紹的Nodejs調(diào)用Dll模塊的方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 詳解Puppeteer 入門教程

    詳解Puppeteer 入門教程

    本篇文章主要介紹了詳解Puppeteer 入門教程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Egret引擎開發(fā)指南之運行項目

    Egret引擎開發(fā)指南之運行項目

    Egret Framework是一款使用TypeScript語言構(gòu)建的開源免費的移動游戲框架。Egret Framework的核心定位是開放,高效,優(yōu)雅。通過它,你可以快速地創(chuàng)建HTML5類型的移動游戲,也可以將游戲項目編譯輸出成為目標移動平臺的原生游戲應(yīng)用。
    2014-09-09
  • Express使用multer實現(xiàn)文件上傳的示例代碼

    Express使用multer實現(xiàn)文件上傳的示例代碼

    這篇文章主要介紹了Express 使用 multer 實現(xiàn)文件上傳的操作步驟,文中通過代碼示例和圖文結(jié)合的方式講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-03-03
  • NodeJS中利用Promise來封裝異步函數(shù)

    NodeJS中利用Promise來封裝異步函數(shù)

    這篇文章主要介紹了NodeJS中利用Promise來封裝異步函數(shù),使用統(tǒng)一的鏈式API來擺脫多重回調(diào)的噩夢,非常的實用的小技能,希望小伙伴們能夠喜歡
    2015-02-02
  • node+axios實現(xiàn)服務(wù)端文件上傳示例

    node+axios實現(xiàn)服務(wù)端文件上傳示例

    這篇文章主要介紹了node+axios實現(xiàn)服務(wù)端文件上傳示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Node.js中同步和異步編程的區(qū)別及使用方法

    Node.js中同步和異步編程的區(qū)別及使用方法

    在Node.js中,同步和異步編程是兩種不同的處理方式。同步方式會阻塞程序的執(zhí)行,而異步方式則不會。通過掌握它們的區(qū)別和使用方法,可以更好地實現(xiàn)程序的性能優(yōu)化和功能擴展。同時,需要注意異步編程中的回調(diào)地獄問題,使用Promise可以更好地處理異步編程
    2023-05-05
  • Node 搭建一個靜態(tài)資源服務(wù)器的實現(xiàn)

    Node 搭建一個靜態(tài)資源服務(wù)器的實現(xiàn)

    這篇文章主要介紹了Node 搭建一個靜態(tài)資源服務(wù)器的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05
  • 使用ExcelJS快速處理Node.js爬蟲數(shù)據(jù)

    使用ExcelJS快速處理Node.js爬蟲數(shù)據(jù)

    Excel.js是一個強大的JavaScript庫,它提供了方法處理Excel文件,例如創(chuàng)建和編輯工作簿、讀取和寫入數(shù)據(jù)、處理行和列、設(shè)置樣式、導入和導出數(shù)據(jù)等,本文介紹使用ExcelJS快速處理Node.js爬蟲數(shù)據(jù)的方法,一起看看吧
    2024-01-01
  • Node.js + express基本用法教程

    Node.js + express基本用法教程

    這篇文章主要介紹了Node.js + express基本用法,結(jié)合實例形式分析了nodejs導入express、路由訪問、數(shù)據(jù)處理等相關(guān)操作技巧,需要的朋友可以參考下
    2019-03-03
  • node.js錯誤處理之npm無法下載第三方包

    node.js錯誤處理之npm無法下載第三方包

    這篇文章主要給大家介紹了關(guān)于node.js錯誤處理之npm無法下載第三方包的相關(guān)資料,文中通過代碼介紹的非常詳細,對大家的學習或者工作具有一定的幫助,需要的朋友可以參考下
    2023-07-07

最新評論