koffi dll examples
koffi 调用 dll 动态库中的方法例子
GitHub 源码 https://github.com/xieerduos/koffi-dll-examples
例子 1 - 调用 dll 中的 add 方法
./example1-calling-dll-functions
目标描述
实现一个 add 加方法调用,使用 JavaScript 调用 dll 的 add 方法,传入 a,b 参数,返回 a+b 的结果。
生成 demodll.dll 文件过程
- 打开 vs 2022
- 新建
- 项目
- 动态链接库(DLL) - 下一步
- 项目名称 demodll - 创建
- 修改 dllmain.cpp 文件,内容如下 - 保存
demodll.cpp
cpp
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <iostream>
extern "C" __declspec(dllexport) int add(int a, int b)
{
return a + b;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
- 顶部菜单 “生成” - “生成解决方案”
node.js 调用代码
- 创建 package.json 文件
powershell
npm init -y
- 安装 koffi
powershell
npm install koffi
- 编写 index.js 调用 dll 代码
js
const koffi = require("koffi");
const path = require("path");
// 加载 DLL
const dllPath = path.join(__dirname, "demodll", "demodll.dll");
const lib = koffi.load(dllPath);
// 定义函数签名(与DLL中导出的函数一致)
// const add = lib.func('add', 'int', ['int', 'int']);
const add = lib.func("int add(int a, int b)");
// 调用函数
const result = add(10, 20);
console.log(`结果为: ${result}`); // 应输出 结果为: 30
把 demodll.dll 拷贝到当前目录下
代码执行
powershell
node -v
v20.18.1
powershell
node index.js
例子 2 - 注册 dll 方法,传入 dll 一个回调函数
./example2-register-dll-callback
目标描述
在 JavaScript 端传入一个 js 的回调函数,在动态库端连续调用此方法。
生成 demodll.dll 文件过程
- 过程与上面的一致,把代码修改一下
demodll.cpp
cpp
// dllmain.cpp
#include "pch.h"
#include <windows.h>
typedef void(__stdcall* CallbackFunc)(int);
// 全局变量
static CallbackFunc g_callback = nullptr;
static HANDLE g_hThread = nullptr;
static volatile bool g_running = false;
// 定时线程函数
DWORD WINAPI TimerThread(LPVOID lpParam)
{
for (int i = 0; i <= 100 && g_running; ++i)
{
if (g_callback)
g_callback(i); // 调用传入的函数指针
Sleep(300); // 等待300毫秒
}
g_running = false;
return 0;
}
// 开始调用函数(导出函数)
extern "C" __declspec(dllexport) void __stdcall StartTimer(CallbackFunc callback)
{
if (g_running) return; // 避免重复启动
g_callback = callback;
g_running = true;
g_hThread = CreateThread(NULL, 0, TimerThread, NULL, 0, NULL);
}
// 停止调用函数(导出函数)
extern "C" __declspec(dllexport) void __stdcall StopTimer()
{
if (!g_running) return;
g_running = false;
WaitForSingleObject(g_hThread, INFINITE);
CloseHandle(g_hThread);
g_hThread = nullptr;
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
顶部菜单 “生成” - “生成解决方案”
把 dll 拷贝到当前目录下的 demodll/demodll.dll
安装 koffi
powershell
npm install
- 编写 JavaScript 调用 dll
js
const koffi = require("koffi");
const path = require("path");
const lib = koffi.load(path.join(__dirname, "demodll", "demodll.dll"));
const CallbackType = koffi.proto("void __stdcall CallbackType(int)");
const StartTimer = lib.func(
"void __stdcall StartTimer(CallbackType *callback)"
);
const StopTimer = lib.func("void __stdcall StopTimer()");
function jsCallback(value) {
console.log("回调收到的数字:", value);
}
const callbackPtr = koffi.register(jsCallback, koffi.pointer(CallbackType));
StartTimer(callbackPtr);
setTimeout(() => {
StopTimer();
koffi.unregister(callbackPtr);
console.log("计时器已停止,回调已注销。");
}, 5000);
console.log("11234");
- 代码执行(当前 dll 仅支持 Windows x64 的电脑),如需 win32 或者 macOS 需自行修改代码和编译
powershell
node -v
v20.18.1
powershell
node index.js
chatgpt
ChatGpt Share https://chatgpt.com/share/67fdf9e0-094c-800b-aa4d-7dbeabf520a5