一、為什么需要使用DLL

  • 需要使用系統(tǒng) API 操作或擴展應用程序;

  • 需要調(diào)用第三方的接口API,特別是與硬件設備進行通信,而這些接口 API 基本上都是通過 C++ 動態(tài)鏈接庫(DLL)實現(xiàn)的;

  • 需要調(diào)用C++實現(xiàn)的一些復雜算法等。

二、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 節(jié)點上加上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')

然后運行程序,出現(xiàn)如下錯誤:

大學生就業(yè)培訓,高中生培訓,在職人員轉(zhuǎn)行培訓,企業(yè)團訓

參考資料:https://github.com/electron/electron/blob/master/docs-translations/zh-CN/tutorial/using-native-node-modules.md,原來是需要把 ffi 重新編譯為適合 electron的模塊。

打開 nodejs 命令行窗口,先執(zhí)行如下命令:

set python=python安裝路徑\python.exe

設置 python 的路徑,切換到項目目錄,然后執(zhí)行如下命令:

"./node_modules/.bin/electron-rebuild" "./node_modules/ffi"

大學生就業(yè)培訓,高中生培訓,在職人員轉(zhuǎn)行培訓,企業(yè)團訓

編譯完成后,運行程序,漂亮的界面終于出現(xiàn)了。

四、使用 ffi 調(diào)用 Widows API 解決一個小缺陷

上篇文章中的仿 QQ 登錄界面還有一個小問題,就是鼠標右鍵點擊窗口的任意地方,都會彈出系統(tǒng)菜單:

大學生就業(yè)培訓,高中生培訓,在職人員轉(zhuǎn)行培訓,企業(yè)團訓

現(xiàn)在使用 ffi 調(diào)用 user32.dll 中的 GetSystemMenu 函數(shù)來解決這個問題,首先新建一個 user32.js 文件,為了展示 ffi ,我多定義了幾個API函數(shù):

大學生就業(yè)培訓,高中生培訓,在職人員轉(zhuǎn)行培訓,企業(yè)團訓

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']]
});

大學生就業(yè)培訓,高中生培訓,在職人員轉(zhuǎn)行培訓,企業(yè)團訓

修改 app.js 文件,首先導入 user32.js:

const user32 = require('./app/scripts/user32').User32

然后修改如下內(nèi)容:

win.once('ready-to-show', () => {
        let hwnd = win.getNativeWindowHandle() //獲取窗口句柄。
        user32.GetSystemMenu(hwnd.readUInt32LE(0), true); //禁用系統(tǒng)菜單.        win.show()
    })

再運行項目,系統(tǒng)菜單就消失的無影無蹤了。

 

最后,所有代碼都已經(jīng)提交到了github:https://github.com/starts2000/ElectronQQLogin,歡迎獲取。

標簽: electronnodejsffi

http://www.cnblogs.com/Starts_2000/p/electron-ffi.html