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

C++宿主在Windows和Linux下如何向C#方法传递byte[]数组输出参数

跨平台C++宿主调用C# byte[]输出参数的封送方案

修正后的C#端实现

输出参数需要额外添加[Out]特性,同时用out修饰参数,告诉运行时将托管数组的内容反向拷贝到非托管内存,该规则在Windows和Linux的CoreCLR中通用:

public static string DoWork(int msgSize, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] out byte[] errMessage)

如果是C侧提前分配数组内存的场景,可以去掉out修饰,仅保留[In, Out]特性即可,这种模式下内存由C管理,避免跨语言内存释放的问题:

public static string DoWork(int msgSize, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] errMessage)

修正后的C++端实现

对应带out修饰的C#方法,函数指针的第二个参数需要改为二级指针,用来接收C#侧输出的数组地址:

// 对应out参数场景的函数指针定义
typedef char* (*doWork_ptr)(int dataSize, char** data);

调用示例:

int errBufSize = 1024; // 提前约定的数组最大长度
char* errBuf = nullptr;
char* returnStr = doWorkInstance(errBufSize, &errBuf);
// 调用完成后errBuf指向C#填充的字节数组,长度为errBufSize
// 需提前约定内存释放规则,避免内存泄漏

对应C++预分配内存的场景,函数指针保持原一级指针定义即可:

typedef char* (*doWork_ptr)(int dataSize, char* data);

跨平台兼容注意事项

  • 上述封送规则在Windows和Linux下完全一致,不需要额外做平台分支适配
  • 返回的字符串默认编码在Windows下为ANSI、Linux下为UTF-8,如需统一编码可在C#方法返回值上添加[return: MarshalAs(UnmanagedType.LPUTF8Str)]标记,避免乱码
  • 优先选择C++侧预分配内存的方案,减少跨语言内存管理的复杂度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:57:03