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

使用Koffi调用带结构体指针的C++函数时出现类型错误

问题分析与解决

你的代码核心问题有两个:一是把结构体类型定义当成了实例直接赋值,二是没有匹配C++的#pragma pack(1)内存对齐规则,另外还有uint64类型和字符串终止符的细节问题。

修正后的完整代码

// 定义结构体类型,必须指定pack=1匹配C++的#pragma pack(1)
const EnvInfoType = koffi.pack('envInfo', {
    dwSize: 'uint32',
    wszAppId: koffi.array('char16', 128),
    u64Qid: 'uint64'
}, 1);

// 创建结构体实例(这一步你之前完全漏掉了)
const envInfo = koffi.new(EnvInfoType);

// 填充结构体大小
envInfo.dwSize = koffi.sizeof(EnvInfoType);

// 处理AppId字符串:转UTF16并添加终止符
const appIdStr = 'xtI7nxn';
const utf16Buffer = new Uint16Array(128);
// 复制字符
for (let i = 0; i < appIdStr.length; i++) {
    utf16Buffer[i] = appIdStr.charCodeAt(i);
}
// C++字符串需要以0结尾,必须添加
utf16Buffer[appIdStr.length] = 0;
// 赋值到结构体字段
envInfo.wszAppId = utf16Buffer;

// uint64类型用BigInt避免溢出
envInfo.u64Qid = 3269309681n;

// 加载动态库并定义函数
const sdk360 = koffi.load(dynamicLib);
const SDK360_Init = sdk360.func('SDK360_Init', 'int', [koffi.pointer(EnvInfoType)]);

// 调用函数:直接传实例即可,Koffi会自动转换为指针
const result = SDK360_Init(envInfo);

关键错误点说明

  1. 类型与实例混淆:
    koffi.pack返回的是结构体的类型定义,不是可直接赋值的实例。必须用koffi.new(类型)创建具体实例后才能操作字段。你之前直接给类型赋值,导致函数调用时传入了错误的类型对象,触发expected envInfo *错误。

  2. 内存对齐不匹配:
    C代码用了#pragma pack(1)取消默认对齐,Koffi定义结构体时必须在koffi.pack的第三个参数指定1,否则结构体的内存布局会和C端不一致,导致参数传递混乱。

  3. uint64类型溢出问题:
    JavaScript的普通数字是64位浮点数,无法精确表示所有uint64值,必须用BigInt(后缀加n)来赋值u64Qid。

  4. 字符串终止符缺失:
    C中WCHAR[]作为字符串需要以0结尾,你的代码只复制了字符,没有添加终止符,可能导致C端读取字符串时出现垃圾数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 14:53:09