iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0

昨天簡單介紹了node-ffi-npi的基本概念,今天要實際使用node-ffi-npi來呼叫我們動態連結函庫內的函式。

  • 首先安裝node-ffi-npi

    pm install --save ffi-napi
    ``
    
    
  • forge.config.js新增擺放動態連結函庫及驅動程式的資料夾lib,打包時要一併加入:

    extraResource": [
    "build",
    "lib"
    ,
    ``
    
    
  • 接著修改main.js,使用ffi-napi模組:

    onst ffi = require('ffi-napi')
    ``
    
    
  • 宣告動態連結函庫SioSdk.dll的路徑:

    ar dllPath = path.join(__dirname, 'lib\\SioSdk.dll');
    f (!isDev) {
     dllPath = path.resolve(__dirname, '..\\lib\\SioSdk.dll');
    
    ``
     由於開發階段的路徑與打包完成後的路徑會有區別,我們利用先前定義的`isDev`來判斷是否為開發階段,進而使用**不同的動態連結函庫路徑**。
    
    
  • 使用ffi.Library,將變數SioSdk連結到SioSdk.dll

    onst SioSdk = ffi.Library(dllPath, {
    'Install': ['bool', []],
    'Open': ['bool', []],
    'Close': ['bool', []],
    'GetCpuFanSpeed': ['uint', []]
    );
    ``
     如同[Day18](https://ithelp.ithome.com.tw/articles/10333653)及[Day19](https://ithelp.ithome.com.tw/articles/10334286)所介紹的標頭檔`SioSdk.h`,將安裝及移除驅動程式的函式和讀取CPU風扇轉速的函式根據`SioSdk.h`裡的**類型**及**參數**,宣告在變數`SioSdk`中。
    
    
  • 依照先前Windows console app的流程,使用SioSdk呼叫SioSdk.dll中的函式來安裝驅動程式:

    / Install and open service
    ar result = SioSdk.Install();
    onsole.log(`Dev:${isDev}. Install service ${result}`);
    esult = SioSdk.Open();
    onsole.log(`Open service ${result}`);
    ``
    
    
  • 然後在Electron應用程式結束時關閉並移除驅動程式:

    pp.on('window-all-closed', () => {
    result = SioSdk.Close();
    if (process.platform !== 'darwin') {
    	app.quit()
    }
    )
    ``
    
    
  • 將原本固定的測試值改為SioSdk.dll中的GetCpuFanSpeed(),回傳CPU風扇實際的轉速:

    pcMain.handle('cpufan', () => GetCpuFanSpeed())
    ``
    
    
  • lib資料夾複製到開發階段Electron應用程式執行的資料夾內:

    copy lib .\node_modules\electron\dist\resources\lib /e /h /c /i
    ``
    
    
  • 修改完成後,執行Electron應用程式,但卻會跳出這個錯誤訊息:

    • 這是由於Electron在v21增加了一個新的功能V8記憶體隔離區,它會造成利用指標讀取記憶體的功能都會使Electron發生錯誤,像是ref-napi。且因為node-ffi-npi使用了ref-napi,所以才會產生上圖的錯誤訊息,其中一個解決方式是將Electron退回v21之前。
  • 輸入下列指令將Electron版本退回至v20.3.8:

    pm install --save-dev electron@20.3.8
    ``
    
    
  • 再次將lib資料夾複製到開發階段Electron應用程式執行的資料夾內,然後重新執行Electron應用程式,可以看到CPU風扇轉速數值顯示在Electron應用程式的UI上了,代表我們成功使用node-ffi-napi呼叫SioSdk.dll中的GetCPuFanSpeed()函式讀取CPU風扇轉速。

在實際使用node-ffi-napi連結動態連結函庫時,一直不斷跳出Uncaught Exception,起初還以為是遇到使用node-ffi-napi的常見問題:

  • Win32 error 126
    • 找不到指定的模組。
  • Win32 error 127
    • 找不到指定的程式。
  • Win32 error 193
    • 不是有效的 Win32 應用程式。

但再三確認相關程式碼後發現並不是以上的問題,在網路上爬了很多文後才了解到是Electron版本的問題,除了降版本以外,也有其他使用者修改了ffi-napiref-napi,可以使用修改過後的版本避開這個問題,有興趣的可以到參考內容中查閱,這次Electron應用程式的原始碼也會放在我個人的repo供各位參考。

參考內容

"Error in native callback" using ffi-napi in electron and electron-builder
Sio-App Repo


上一篇
Day26 Electron應用程式-6
下一篇
Day28 Electron應用程式-8
系列文
Windows Driver + Electron 學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言