electron调用dll 方案

在 Electron(Node.js)中调用 Windows DLL,主流有 纯 JS 直接调用C++ 原生扩展进程间通信 三大类方案。下面按 推荐度 + 上手难度 详细说明。


一、纯 JS 直接调用(最常用,无 C++ 代码)

1. Koffi(现代首选,2025--2026 推荐)

  • 优势 :维护活跃、性能好、兼容新版 Electron、支持同步/异步、结构体、回调、stdcall/cdecl
  • 依赖koffi(无需 ref/ref-struct
  • 安装
bash 复制代码
npm install koffi
  • 示例(调用 DLL 函数)
javascript 复制代码
const koffi = require('koffi');

// 1. 加载 DLL
const lib = koffi.load('./mydll.dll'); // 或绝对路径

// 2. 声明函数:返回类型 + [参数类型]
// 例:int Add(int a, int b);
const Add = lib.func('Add', 'int', ['int', 'int']);

// 3. 调用
const sum = Add(10, 20);
console.log(sum); // 30

// 4. 结构体/指针(简单示例)
const Point = koffi.struct({ x: 'int', y: 'int' });
const GetPoint = lib.func('GetPoint', Point, []);
const pt = GetPoint();
console.log(pt.x, pt.y);
  • 适用绝大多数场景(硬件 SDK、系统 DLL、第三方库)

2. ffi-napi + ref-napi(传统主流)

  • 优势:生态成熟、文档多、大量旧项目在用
  • 问题Electron 20.3.8+ 可能内存保护报错,需用 fork 版或降级
  • 安装
bash 复制代码
npm install ffi-napi ref-napi ref-struct-napi
  • 示例
javascript 复制代码
const ffi = require('ffi-napi');
const ref = require('ref-napi');

const lib = ffi.Library('./mydll.dll', {
  Add: ['int', ['int', 'int']]
});

const sum = lib.Add(10, 20);
console.log(sum);
  • 适用老项目维护不推荐新项目

二、C++ Node 扩展(性能/复杂交互首选)

1. Node-API (N-API) + node-addon-api

  • 原理 :用 C++ 写一层 Node 原生扩展(.node) ,在 C++ 里 LoadLibrary/调用 DLL,再暴露给 JS
  • 优势最稳定、性能最高、复杂结构体/回调/内存完全可控
  • 劣势必须会 C++ 、需配置 binding.gyp、跨平台编译
  • 步骤
  1. 初始化
bash 复制代码
npm init
npm install node-addon-api
npm install -g node-gyp
  1. 编写 binding.gyp
json 复制代码
{
  "targets": [{
    "target_name": "mydll_bridge",
    "sources": ["bridge.cpp"],
    "include_dirs": ["<!@(node -p \"require('node-addon-api').include\")"],
    "dependencies": ["<!(node -p \"require('node-addon-api').gyp\")"],
    "libraries": ["../libs/mydll.lib"] // 配套 .lib
  }]
}
  1. 编写 bridge.cpp(C++ 桥接)
cpp 复制代码
#include <napi.h>
#include <windows.h>

typedef int (*AddFunc)(int, int);

Napi::Value Add(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  HMODULE dll = LoadLibraryA("./mydll.dll");
  AddFunc add = (AddFunc)GetProcAddress(dll, "Add");
  int a = info[0].As<Napi::Number>();
  int b = info[1].As<Napi::Number>();
  int res = add(a, b);
  FreeLibrary(dll);
  return Napi::Number::New(env, res);
}

Napi::Object Init(Napi::Env env, Napi::Object exports) {
  exports.Set("Add", Napi::Function::New(env, Add));
  return exports;
}

NODE_API_MODULE(mydll_bridge, Init)
  1. 编译
bash 复制代码
node-gyp configure
node-gyp build --arch=x64
  1. JS 调用
javascript 复制代码
const bridge = require('./build/Release/mydll_bridge.node');
console.log(bridge.Add(10, 20)); // 30
  • 适用高频调用、复杂回调、硬件 SDK、内存敏感场景

三、其他方案(特殊场景)

1. edge-js(C#/.NET DLL)

  • 直接调用 .NET Framework/.NET Core DLL(C#/VB)
bash 复制代码
npm install edge-js
javascript 复制代码
const edge = require('edge-js');
const hello = edge.func(() => {
  /*
  async (string input) => {
    return "Hello " + input;
  }
  */
});
hello("Electron", (err, res) => { console.log(res); });
  • 适用仅 .NET DLL

2. 进程间通信(IPC/管道/HTTP)

  • 写一个 C++/C# 控制台程序 封装 DLL,Electron 通过 child_process / WebSocket / HTTP 通信
  • 优势:完全隔离崩溃、跨语言、不污染主进程
  • 劣势性能低、通信复杂
  • 适用DLL 不稳定易崩溃、需独立进程隔离

3. Win32 API 直接调用(系统 DLL)

  • user32.dll / kernel32.dllKoffi/ffi-napi 直接调用
javascript 复制代码
// Koffi 调用 MessageBoxW
const user32 = koffi.load('user32.dll');
const MessageBoxW = user32.func('MessageBoxW', 'int', ['ptr', 'wstr', 'wstr', 'uint']);
MessageBoxW(null, 'Hello Electron', 'Title', 0);

四、方案对比(2026 最新)

方案 上手难度 稳定性 性能 维护 适用场景
Koffi ⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ 活跃 新项目首选、绝大多数 DLL
ffi-napi ⭐⭐ ⭐⭐⭐ ⭐⭐⭐ 停滞 老项目、兼容旧 Electron
Node-API 扩展 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ 官方 高性能、复杂交互、硬件 SDK
edge-js ⭐⭐⭐ ⭐⭐⭐ ⭐⭐ 一般 仅 .NET DLL
IPC 进程 ⭐⭐⭐⭐ ⭐⭐⭐⭐ 隔离不稳定 DLL

五、常见坑与解决

  1. 架构不匹配
    • DLL 是 x86 → Electron 必须用 32 位(--arch=ia32
    • DLL 是 x64 → Electron 必须用 64 位
  2. 依赖缺失(报错 126/127)
    • Dependency Walker 查看缺少 VC++ 运行库/Qt 等
    • 把依赖 DLL 放到 同目录
  3. 调用约定
    • Koffi:自动支持 stdcall(Windows API)/ cdecl
    • ffi-napi:ffi.C(cdecl)/ ffi.Win32(stdcall)
  4. Electron 版本兼容
    • 优先 Koffi:兼容最新版
    • ffi-napi:20.3.8+ 报错 → 用 ffi-napi@latest 或 fork 版

六、推荐路线

  • 新项目、无 C++Koffi
  • 老项目、已用 ffi-napi → 继续维护
  • 高性能/硬件 SDK/复杂回调Node-API 扩展
  • 仅 .NET DLLedge-js
  • DLL 易崩溃独立进程 IPC

相关推荐
IT_陈寒2 小时前
Java线程池用完不关闭?小心内存泄漏找上门
前端·人工智能·后端
ZHENGZJM2 小时前
前端基石:React + Vite + TypeScript 项目搭建
前端·react.js·typescript
SP八岐大兔2 小时前
NPM管理OpenClaw安装、卸载及运维命令
运维·前端·npm·openclaw
在路上`2 小时前
前端常见问题汇总(十一)_融合AI
前端
小江的记录本2 小时前
【JEECG Boot】 《JEECG Boot 数据字典使用教程》(完整版)
java·前端·数据库·spring boot·后端·spring·mybatis
Access开发易登软件2 小时前
在 Access 中实现 Web 风格 To Do List
前端·数据结构·microsoft·list·vba·access·access开发
小李云雾2 小时前
Python Web 路由详解:核心知识点全覆盖
开发语言·前端·python·路由
cd ~/Homestead2 小时前
Vue 配置跨域的两种方法
前端·javascript·vue.js
Moment2 小时前
AI 全栈时代,为什么推荐 NodeJs 服务端使用 NestJs
前端·javascript·后端