摘要:指針和引用假設動態庫中有函數如下第二個參數為結構體指針,第三個參數是一個引用。我這里選擇的是然后找到,下載替換掉重編譯和輸入版本號,這里實用的是為或者參考資料通過在中調用動態鏈接庫文件厚顏無恥加上自己的博客
0x01. 使用的 npm 包
首先要安裝 node-gyp, 用來重新編譯依賴包。
npm instal -g node-gyp
然后主要用到下面三個包:
node-ffi -- 使用Javascript調用動態庫
ref -- 用來定義數據類型,提供指針功能
ref-array -- 用Buffer來實現C語言中的 array 數據類型
npm install ffi //這個命令會同時安裝上 ref、ref-struct npm instal ref-array0x02. 測試NODEJS調用
要使用動態庫中的函數,首先要對動態庫里的函數進行聲明。
比如在 Test.dll 庫中,有兩個函數如下:
void init(string name, int port); string hello(int times);
在 js中進行聲明的方法如下:
var ffi = require("ffi"); var Test = ffi.Library("Test.dll",{ "init": ["void",["string","int"]], "hello": ["string", ["int"]] }); #規則就是 "函數名":["返回值數據類型":["參數數據類型",...,"參數數據類型"]]
聲明完成后,就可以進行調用了
Test.init("COM1", 9300); Test.hello(5);
這里用簡單的數據類型,來講解調用動態庫的大致流程。剩下比較復雜的地方在于如何模擬像 指針、結構體、數組 等比較復雜的數據類型。
0x03. 結構體、指針、數組的轉化 1. 結構體結構體需要用到"ref-struct"這個包。假設有以下結構體:
typedef struct { byte UID[16]; /*餐盤標簽 UID,16 進制*/ byte UType[6]; /*餐盤類型,10 進制*/ int ProdNo; /*菜品編碼,10 進制*/ int ProdPrice; /*菜品價格,價格以分為單位,10 進制*/ } DishInfo;
int類型的好辦,可以直接使用 ref包里含有的類型 ref.types.int。
UID和UType是兩個bype類型的數組,需要使用ref-array進行模擬。
var refStruct = require("ref-struct"); var refArray = require("ref-array"); var DishInfo = refStruct({ "UID": refArray("byte", 16), "UType": refArray("byte", 6), "ProdNo": ref.types.int, "ProdPrice": ref.types.int });2. 指針和引用
假設動態庫中有函數如下, 第二個參數為結構體指針, 第三個參數是一個int 引用。
int Read(int port, DishInfo * pInfo, int &Count);
在聲明函數的時候,就需要指明指針和引用的數據類型。示例如下:
var ffi = require("ffi"); var ref = require("ref"); var refStruct = require("ref-struct"); var refArray = require("ref-array"); var DishInfo = refStruct({ "UID": refArray("byte", 16), "UType": refArray("byte", 6), "ProdNo": ref.types.int, "ProdPrice": ref.types.int }); //數據類型 var intPointer = ref.refType("int"); var DishInfoArrType = refArray(DishInfo); //定義了DishInfo數組類型 var Test = ffi.Library("Test.dll",{ "init": ["void",["string","int"]], "hello": ["string", ["int"]], "Read": ["int", ["int", DishInfoArrType, intPointer]] }); //實例化 var count = ref.alloc("int"); var DishInfoArr = DishInfoArrType(3); Test.Read(11, DishInfoArray, count); //使用deref()獲取引用的實際值 var actualCount = count.deref();0x04. NW 適配
使用NodeJS直接調用沒問題后,就可以使用 node-gyp 編譯適配 NW 的包了, 這里只說明window環境下的使用方法。
1. 搭建編譯環境
安裝 Visual Studio 2015
> ? [Windows Vista / 7 only] 需要安裝 [.NET Framework 4.5.1](http://www.microsoft.com/en-us/download/details.aspx?id=40773)
安裝 python 2.7 (不要裝3.x.x,不支持),裝完后運行
npm config set python python2.7
設置visualstudio版本
npm config set msvs_version 20152. 修改 win_delay_load.cc
打開 Github - nw.js repository, 然后切換自己使用的nw 版本分支。
我這里選擇的是 nw14, 然后找到 tools/win_delay_load_hook.cc, 下載替換掉 %APPDATA% pm ode_modules ode-gypsrcwin_delay_load_hook.cc
3. node-gyp 重編譯 ffi 和 ref# --target 輸入nw 版本號,這里實用的是 v0.14.3, arch為 ia32 或者 x64 cd node_modules/ffi node-gyp configure --target=0.14.3 --arch=ia32 node-gyp build cd node_modules/ref node-gyp configure --target=0.14.3 --arch=ia32 node-gyp build0x05. 參考資料
通過ffi在node.js中調用動態鏈接庫(.so/.dll文件)
Use Native Node Modules
厚顏無恥加上自己的博客 XD
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/80342.html
摘要:前言在上一篇文章使用開發跨平臺桌面應用一中,我們將結合起來,使用編寫核心業務邏輯,并編譯成庫提供給的界面調用,但是在上一篇文章中發現遇到了很多問題,尤其是的版本和編譯出來的版本必須要一致,否則會無法調用成功,這就很坑了,所以為了改變這一情況 前言 在上一篇文章使用Rust + Electron開發跨平臺桌面應用 ( 一 )中,我們將Rust + Electron結合起來,使用Rust編...
摘要:項目背景最近上三年級兒子的英語老是記不住單詞,而他們又在上科學課,老師讓練打字。打字和英語學習都沒太適合小家伙的實際情況,因此就花了一個周末寫下了這個項目。題庫為文件,存在指定目錄中。運行方法全局安裝克隆源代碼安裝依賴庫運行項目 項目背景 最近上三年級兒子的英語老是記不住單詞,而他們又在上科學課,老師讓練打字。打字和英語學習都沒太適合小家伙的實際情況,因此就花了一個周末寫下了這個項目。...
摘要:遠端代碼下發,有什么設計思路一般大家都用用別人的,總不好。老王造了個輪子,我來描述一下。代碼,采用打包。蘋果自己實現的用到了,這個庫老王也使用了,,就是把一個語言暴露出來的接口,能讓其他語言來調用。 iOS 遠端代碼下發,有什么設計思路 ? 一般大家都用 JSPatch? 用別人的,總不好。老王造了個輪子,我來描述一下。 老王 Patch, 挺先進的。JavaScript 代碼, 采用...
摘要:擴展已經通過,正式成為的捆綁擴展庫。第一步,從頭文件把主要的數據結構和函數聲明復制出來目前不支持預處理器除了和,所以宏定義要自己展開。 FFI擴展已經通過RFC,正式成為PHP 7.4的捆綁擴展庫(Bundled Extensions)。 什么是FFI FFI(Foreign Function Interface),即外部函數接口,是指在一種語言里調用另一種語言代碼的技術。PHP的FF...
閱讀 1384·2021-09-24 10:26
閱讀 1695·2019-08-30 14:14
閱讀 2105·2019-08-29 16:54
閱讀 367·2019-08-29 14:09
閱讀 1477·2019-08-29 12:55
閱讀 930·2019-08-28 18:13
閱讀 1582·2019-08-26 13:39
閱讀 2567·2019-08-26 11:43