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

如何将C#返回的System::Array转换为C++兼容数据类型

在C++/CLI中转换C#结构体数组为原生C++类型的方案

首先得提一个关键细节:你C#里的PJSONInfo结构体字段都是私有的,C++/CLI根本访问不到这些值,所以第一步要先修正C#代码,把字段改成public(或者添加public属性),不然后续转换无从谈起。

步骤1:修正C#结构体的访问权限

把PJSONInfo的字段改为public,让C++/CLI能读取这些字段的值:

namespace JSON {
    public struct PJSONInfo {
        public string sSetting;
        public double dMinVal;
        public double dMaxVal;
        public string sUnits;
    }
    public interface iCalFunction {
        PJSONInfo[] ReadJSON();
    }
    public class JSONReaderClass : iCalFunction {
        public PJSONInfo[] ReadJSON() {
            IList<PJSONInfo> JSONList = new List<PJSONInfo>();
            // 保留你的填充逻辑
            PJSONInfo[] ReturningJSONArray = JSONList.ToArray();
            return ReturningJSONArray ;
        }
    }
}

步骤2:定义原生C++结构体

在C++代码里定义一个和C#结构体字段一一对应的原生结构体,方便存入vector:

// 原生C++结构体,匹配C#的PJSONInfo
struct NativeJSONInfo {
    std::wstring sSetting; // C# string是UTF-16,用wstring对应最直接
    double dMinVal;
    double dMaxVal;
    std::wstring sUnits;
};

步骤3:实现托管数组到原生vector的转换

利用C++/CLI提供的封送工具,把System::Array里的每个元素逐个转换为原生结构体,存入vector。记得要包含封送相关的头文件:

首先添加必要的头文件:

#include <vector>
#include <string>
#include <msclr/marshal_cppstd.h>

然后修改你的读取函数:

class CReadingClass {
public:
    msclr::auto_gcroot<JSON::JSONReaderClass^> pJSONClass;
};

int ReadJSONFromJSONReader() {
    CReadingClass* pReadClass = new CReadingClass();
    pReadClass->pJSONClass = gcnew JSON::JSONReaderClass();
    System::Array^ JSONSetting = pReadClass->pJSONClass->ReadJSON();

    // 用于存储原生C++结构体的vector
    std::vector<NativeJSONInfo> nativeJSONList;

    // 遍历托管数组的每个元素
    for each (JSON::PJSONInfo item in JSONSetting) {
        NativeJSONInfo nativeItem;
        // 封送字符串:System::String^ 转 std::wstring
        nativeItem.sSetting = msclr::interop::marshal_as<std::wstring>(item.sSetting);
        // 数值类型可以直接赋值,因为都是值类型
        nativeItem.dMinVal = item.dMinVal;
        nativeItem.dMaxVal = item.dMaxVal;
        nativeItem.sUnits = msclr::interop::marshal_as<std::wstring>(item.sUnits);
        
        nativeJSONList.push_back(nativeItem);
    }

    // 现在nativeJSONList就是纯原生C++可以直接使用的结构体集合了
    // 在这里添加你的后续业务逻辑即可...

    // 记得释放手动分配的原生内存
    delete pReadClass;
    return 1;
}

一些注意事项

  • 字符串编码:如果你的原生代码需要用std::string而不是std::wstring,可以把marshal_as的目标改成std::string,默认会把UTF-16的C#字符串转成UTF-8的std::string,如果有特殊编码需求需要额外处理。
  • 内存管理:CReadingClass是用new分配的原生对象,一定要记得delete;而托管对象(比如JSONReaderClass^)由CLR垃圾回收机制处理,不用手动释放。
  • 替代方案:如果你的后续逻辑还是在C++/CLI环境中运行,其实可以直接使用System::Array或者转换为System::Collections::Generic::List<JSON::PJSONInfo>,不需要转成原生vector——只有当需要和纯原生C++代码交互时,才需要做这种封送转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 21:52:36