You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Koffi调用mylib.dll的setup函数时无法正确获取输出值求助

问题分析与解决方案

你的代码核心问题在于对wchar_t**类型输出参数的内存分配和读取逻辑错误,以下是具体修正步骤:

1. 错误点拆解

  • 函数参数wchar_t**表示DLL会返回一个指向宽字符串的指针(即DLL内部分配内存后,把指针地址写入你传入的变量),但你用koffi.alloc('wchar_t*', 1024+1)分配了1025个指针大小的内存,完全不符合需求——你只需要分配1个指针大小的空间来存储DLL返回的指针地址。
  • 读取输出时,你直接对wchar_t**类型的缓冲区解码,而正确逻辑是先读取缓冲区里的wchar_t*指针,再解码这个指针指向的宽字符串。

2. 修正方案(两种方式任选)

方式一:使用Koffi的koffi.out简化输出参数处理

这是Koffi推荐的处理输出指针的方式,无需手动分配内存:

const koffi = require('koffi');

const lib = koffi.load('mylib.dll');
// 用koffi.out标记输出参数
const setup = lib.func('setup', 'int', ['const wchar_t *', koffi.out('wchar_t *')]);

const inputJson = {
    "config": {
        "pass": "123"
    }
}
const jsonString = JSON.stringify(inputJson);

function stringToWideCharBuffer(str) {
    const buffer = Buffer.alloc((str.length + 1) * 2);
    buffer.write(str, 0, 'utf16le');
    return buffer;
}

const jsonConfig = stringToWideCharBuffer(jsonString);

// 直接声明变量接收输出指针
let jsonOutPtr = null;
const result = setup(jsonConfig, jsonOutPtr);

console.log(result);
if (result === 0) {
    // 直接解码指针指向的宽字符串
    const outputStr = koffi.decode(jsonOutPtr, 'wchar_t*');
    console.log('Output JSON:', outputStr);
    
    // 重要:如果DLL用malloc分配内存,必须调用DLL提供的释放函数(比如free_output)避免内存泄漏
    // const freeOutput = lib.func('free_output', 'void', ['wchar_t *']);
    // freeOutput(jsonOutPtr);
} else {
    console.error('setup failed with code:', result);
}

方式二:手动处理指针分配与读取

如果你想手动管理内存,按以下步骤修改:

const koffi = require('koffi');

const lib = koffi.load('mylib.dll');
const setup = lib.func('setup', 'int', ['const wchar_t *', 'wchar_t **']);

const inputJson = {
    "config": {
        "pass": "123"
    }
}
const jsonString = JSON.stringify(inputJson);

function stringToWideCharBuffer(str) {
    const buffer = Buffer.alloc((str.length + 1) * 2);
    buffer.write(str, 0, 'utf16le');
    return buffer;
}

const jsonConfig = stringToWideCharBuffer(jsonString);

// 仅分配1个指针大小的内存,用于存储DLL返回的wchar_t*地址
const jsonOutPtrBuf = koffi.alloc('wchar_t*');

const result = setup(jsonConfig, jsonOutPtrBuf);

console.log(result);
if (result === 0) {
    // 第一步:读取缓冲区里的wchar_t*指针
    const jsonOutPtr = koffi.decode(jsonOutPtrBuf, 'wchar_t*');
    // 第二步:解码指针指向的宽字符串
    const outputStr = koffi.decode(jsonOutPtr, 'wchar_t*');
    console.log('Output JSON:', outputStr);
    
    // 同样,记得调用DLL的内存释放函数(如果需要)
    // const freeOutput = lib.func('free_output', 'void', ['wchar_t *']);
    // freeOutput(jsonOutPtr);
} else {
    console.error('setup failed with code:', result);
}

关键注意事项

  • 如果DLL是通过malloc分配的输出字符串内存,必须调用DLL提供的对应释放函数(比如free_output),否则会造成内存泄漏——不要用Node.js的free或koffi.free,因为DLL和Node.js可能使用不同的内存分配器。
  • 确认你的DLL确实是通过wchar_t**返回字符串,部分DLL可能要求调用者预先分配缓冲区,此时函数参数会包含缓冲区大小(比如int setup(const wchar_t* input, wchar_t* output, size_t buf_size)),这种情况下你需要调整内存分配和函数定义。

内容的提问来源于stack exchange,提问作者hhpr98

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 08:28:13