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

使用Koffi传递多维数组作为DLL参数的技术问询

解决Koffi调用DLL时多维数组参数的问题

问题a:DLL函数的定义方式

对于DLL中声明的unsigned char myVar[][128]参数,在C语言中它等价于指向长度为128的unsigned char数组的指针(即unsigned char (*myVar)[128])。在Koffi中不需要使用koffi.struct,直接用指针+数组类型即可定义:

  1. 先定义单个128字节的数组类型:
    const ByteArray128 = koffi.array('uint8_t', 128);
    
  2. 然后在函数定义中,将该参数声明为指向上述数组类型的指针:
    const myDllFunc = koffi.load('my.dll').func('myDllFunc', 'void', [koffi.pointer(ByteArray128)]);
    
    注意:C语言无法自动获取多维数组的第一维度长度,通常需要额外传入该长度作为函数参数(比如你的场景中是128)。

问题b:JS数组的处理与传参

不能直接将你创建的JS二维数组myBuf作为参数传入DLL——JS数组的内存布局和C语言的连续多维数组完全不同,必须先将JS数据拷贝到Koffi分配的连续内存块中,调用完成后再将数据读回JS数组:

完整步骤示例

// 1. 定义DLL函数和数组类型
const ByteArray128 = koffi.array('uint8_t', 128);
const myDll = koffi.load('your_dll_file.dll');
// 第二个参数传入第一维度长度(128),供DLL内部使用
const myFunc = myDll.func('myFunc', 'void', [koffi.pointer(ByteArray128), 'int']);

// 2. 你的原始JS数组
const myBuf = new Array(128).fill(0).map(() => new Array(128).fill(0));

// 3. 分配连续内存块,对应128个ByteArray128数组
const cBuffer = koffi.allocate(koffi.array(ByteArray128, 128), koffi.ALLOC_NORMAL);

try {
  // 4. 将JS数组数据拷贝到C内存中
  const typedArray = new Uint8Array(128 * 128);
  for (let i = 0; i < 128; i++) {
    typedArray.set(myBuf[i], i * 128);
  }
  koffi.memcpy(cBuffer, typedArray.buffer, 128 * 128);

  // 5. 调用DLL函数,传入内存指针和数组长度
  myFunc(cBuffer, 128);

  // 6. 将DLL填充的数据读回JS数组
  const resultTypedArray = new Uint8Array(koffi.view(cBuffer, 128 * 128, 'uint8_t'));
  for (let i = 0; i < 128; i++) {
    myBuf[i] = Array.from(resultTypedArray.subarray(i * 128, (i + 1) * 128));
  }
} finally {
  // 7. 释放分配的内存,避免泄漏
  koffi.free(cBuffer);
}

关键说明

  • 必须使用koffi.allocate分配C风格的连续内存,确保DLL能正确读写数据。
  • 用Uint8Array作为中间层,简化JS数组和C内存之间的数据拷贝操作。
  • 调用完成后务必释放内存,避免内存泄漏问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 09:46:16