Skip to content

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 文件过程

  1. 打开 vs 2022
  2. 新建
  3. 项目
  4. 动态链接库(DLL) - 下一步
  5. 项目名称 demodll - 创建
  6. 修改 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;
}
  1. 顶部菜单 “生成” - “生成解决方案”

node.js 调用代码

  1. 创建 package.json 文件
powershell
npm init -y
  1. 安装 koffi
powershell
npm install koffi
  1. 编写 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
  1. 把 demodll.dll 拷贝到当前目录下

  2. 代码执行

powershell
node -v
v20.18.1
powershell
node index.js

例子 2 - 注册 dll 方法,传入 dll 一个回调函数

./example2-register-dll-callback

目标描述

在 JavaScript 端传入一个 js 的回调函数,在动态库端连续调用此方法。

生成 demodll.dll 文件过程

  1. 过程与上面的一致,把代码修改一下

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;
}
  1. 顶部菜单 “生成” - “生成解决方案”

  2. 把 dll 拷贝到当前目录下的 demodll/demodll.dll

  3. 安装 koffi

powershell
npm install
  1. 编写 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");
  1. 代码执行(当前 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