使用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);
关键错误点说明
类型与实例混淆:
koffi.pack返回的是结构体的类型定义,不是可直接赋值的实例。必须用koffi.new(类型)创建具体实例后才能操作字段。你之前直接给类型赋值,导致函数调用时传入了错误的类型对象,触发expected envInfo *错误。内存对齐不匹配:
C代码用了#pragma pack(1)取消默认对齐,Koffi定义结构体时必须在koffi.pack的第三个参数指定1,否则结构体的内存布局会和C端不一致,导致参数传递混乱。uint64类型溢出问题:
JavaScript的普通数字是64位浮点数,无法精确表示所有uint64值,必须用BigInt(后缀加n)来赋值u64Qid。字符串终止符缺失:
C中WCHAR[]作为字符串需要以0结尾,你的代码只复制了字符,没有添加终止符,可能导致C端读取字符串时出现垃圾数据。
内容的提问来源于stack exchange,提问作者jianjun wang
相关产品推荐
相关产品推荐

