网站维护排名,商贸公司网站模板,在线制作国庆头像,温州论坛703▒ 目录 ▒ #x1f6eb; 导读需求开发环境 1️⃣ FFI概念优点注意事项 2️⃣ 【废弃】node-ffi3️⃣ node-ffi-napi安装#xff08;windows系统下#xff09;示例#xff1a;MessageBoxA、NtSuspendProcess 4️⃣ node-win32-api安装示例#xff1a;查找窗口并设置窗口标… ▒ 目录 ▒ 导读需求开发环境 1️⃣ FFI概念优点注意事项 2️⃣ 【废弃】node-ffi3️⃣ node-ffi-napi安装windows系统下示例MessageBoxA、NtSuspendProcess 4️⃣ node-win32-api安装示例查找窗口并设置窗口标题 5️⃣ hmc-win32安装示例 文章小结 参考资料 导读
需求 C开发中经常遇到使用脚本语言如lua、python等提供更为灵活的更新操作。而脚本调用dll又得导出接口。为了不更新二进制代码往往通过ffi的形式为脚本语言增加调用dll的功能。 electron同样支持js调用原生模块的功能参考 Node 原生模块 https://www.electronjs.org/zh/docs/latest/tutorial/using-native-node-modules。然而为了更加丰富electron的功能我们是否可以提供类似lua等脚本语言调用原生dll的接口能力呢 这就是今天我们要讲的FFI。 开发环境
版本号描述文章日期2023-12-10操作系统Win11 - 21H2 - 22000.1335
1️⃣ FFI
概念 Foreign Function Interface外语函数接口FFI是指一种在不同编程语言之间调用函数的方式。FFI 可以使语言 A 的程序能调用由语言 B 编写的函数从而实现两种语言之间的交互。FFI 可以使用用户态库或者内核态库实现并且可以在不同的操作系统上使用。FFI 的一般实现方式是通过在目标语言如 C中编写一个封装函数然后在调用方语言中使用该封装函数来调用目标函数。 优点 使用 FFI 有以下几个优势 跨语言调用FFI 使得在不同编程语言之间进行函数调用成为可能。使用外部库FFI 使得可以调用外部库中的函数而不需要将其代码集成到程序中。提高效率FFI 使得可以调用由其他编程语言编写的高效函数提高程序的效率。利用已有的库资源FFI 使得可以利用已有的由其他语言编写的库资源避免重复开发。 总之FFI 是一种很灵活的技术可以帮助程序员在不同编程语言之间进行函数调用提高程序的效率和扩展性。 注意事项 尽管FFI有大量优势我们依然需要注意 如调用方和被调用方的类型参数和返回值的转换调用方与被调用方的内存管理等问题。 2️⃣ 【废弃】node-ffi 网上搜索node ffi会出现大量的关于库node-ffi的文章其git地址为https://github.com/node-ffi/node-ffi。 从git上可以看到该库已经从19年不再更新了而node和electron的版本日新月异经过测试该库在新版本的node中已经无法正常运行可以完全放弃了。 3️⃣ node-ffi-napi 通过github小编发现了替代库node-ffi-napi https://github.com/node-ffi-napi/node-ffi-napi该库在node16及node18下测试均正常。 安装windows系统下 步骤一确保您已安装所有必要的构建适合您平台的工具node-gyp 步骤二然后调用下面语句 npm install ffi-napi 注意这里会发现不是node-ffi-napi而是ffi-napi。 示例MessageBoxA、NtSuspendProcess node-ffi-napi提供了对象Library其构造函数生成dll对应的接口集合。 参数一为dll名称 参数二为对象表示所有要用到的api接口。 下面分别通过MessageBoxA演示UI能力以及NtSuspendProcess挂起某进程。 import ffi from ffi-napifunction 测试ffi_napi() {var current ffi.Library(user32.dll, {MessageBoxA: [ int, [ int, int , int , int ] ]});current.MessageBoxA(0,0,0,0); // 1234// NTSTATUS NTAPI NtSuspendProcess(HANDLE ProcessHandle)var ntdll ffi.Library(ntdll.dll, {NtSuspendProcess: [ int, [ int ] ]});ntdll.NtSuspendProcess(-1);
}测试ffi_napi()
4️⃣ node-win32-api node-win32-api是基于node-ffi-napi的一个纯js库封装了部分接口和数据结构方便用户调用。 github地址https://github.com/waitingsong/node-win32-api 安装 npm install win32-api 示例查找窗口并设置窗口标题
// **Find calcs hWnd, need running a calculator program manually at first**/*** Exposed modules:* Comctl32: Comctl32 from lib/comctl32/api* Kernel32: kernel32 from lib/kernel32/api* User32: user32 from lib/user32/api*/
import { Kernel32, User32 } from win32-api/promise
import ref from ref-napiconst knl32 Kernel32.load()
const user32 User32.load()// const user32 load([FindWindowExW]) // load only one api defined in lib/{dll}/api from user32.dllconst title Calculator\0 // null-terminated string
// const title 计算器\0 // null-terminated string 字符串必须以\0即null结尾!const lpszWindow Buffer.from(title, ucs2)
const hWnd await user32.FindWindowExW(0, 0, null, lpszWindow)assert((typeof hWnd string hWnd.length 0) || hWnd 0)
console.log(buf: , hWnd)// Change title of the Calculator
const res await user32.SetWindowTextW(hWnd, Buffer.from(Node-Calculator\0, ucs2))
if ( ! res) {console.log(SetWindowTextW failed)
}
else {console.log(window title changed)
}5️⃣ hmc-win32 hmc-win32 是中国香港的小哥写的库实现了各种常用的函数的封装貌似对标自动化库autoitX。 该库通过C实现的功能十分丰富作者自己说自测完善可放心使用。 github地址https://github.com/kihlh/hmc-win32 安装 npm i hmc-win32 示例 枚举进程列表 import hmc from hmc-win32;function 测试hmc() {// console.log(hmc)let procList hmc.Process.getDetailsList()console.log(procList)
}测试hmc()文章小结 上述是对electron使用ffi扩展的各种尝试如若不满足需求。 可通过Node 原生模块开发自己需要的功能。其实ffi也是原生模块的一个应用而已。 参考资料
Node 原生模块 https://www.electronjs.org/zh/docs/latest/tutorial/using-native-node-modules调用 c原生 dll https://zh-sky.gitee.io/electron-vue-template-doc/Overview/advanced/ffi.htmlnode-win32-api https://github.com/waitingsong/node-win32-apihmc-win32 https://github.com/kihlh/hmc-win32 ps 文章中内容仅用于技术交流请勿用于违规违法行为。