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

如何将C#中的嵌套数组正确封送到C++ DLL并转换为vector?

问题根因

你遇到的There is no marshaling support for nested arrays报错是.NET互操作的原生限制:默认封送器不支持直接封送托管锯齿数组(double[][])到非托管C代码。同时你原有C代码中的vector构造逻辑也存在类型不匹配问题:double*[]的元素是指针类型,无法直接初始化存储double值的array<double,2>,就算绕过封送错误也会得到乱码结果。

解决方案1:子数组长度固定时使用结构体数组(适配你的现有场景)

你的场景中每个子数组固定为2个double元素,通过定义内存布局一致的结构体传递是最简单的方案。

C#端代码修改

// 定义顺序内存布局的结构体,和C++端array<double,2>内存完全对齐
[StructLayout(LayoutKind.Sequential)]
public struct DoublePair
{
    public double Value1;
    public double Value2;
}

class Program
{
    [DllImport("./x64/Debug/Test.dll")]
    public static extern void analysis([MarshalAs(UnmanagedType.LPArray)] DoublePair[] values, int len);

    static void Main(string[] args)
    {
        List<DoublePair> lst = new List<DoublePair>();
        lst.Add(new DoublePair { Value1 = 1.2, Value2 = 1.3 });
        lst.Add(new DoublePair { Value1 = 2.3, Value2 = 2.4 });
        lst.Add(new DoublePair { Value1 = 3.4, Value2 = 3.5 });

        analysis(lst.ToArray(), lst.Count);
    }
}

C++端代码修改

#include <vector>
#include <array>
#include <iostream>

extern "C" __declspec(dllexport) void __cdecl analysis(std::array<double,2> values[], int len)
{
    using namespace std;
    // 此处vector范围构造的写法是正确的
    vector<array<double,2>> ind(values, values + len);

    for (int i = 0; i < ind.size(); i++)
    {
        cout << ind[i][0] << " " << ind[i][1] << endl;
    }
}
解决方案2:子数组长度可变时使用展平数组

如果子数组长度不固定,可以将嵌套数组展平为一维数组传递,同时额外传递每个子数组的长度参数。

C#端代码修改

[DllImport("./x64/Debug/Test.dll")]
public static extern void analysis([MarshalAs(UnmanagedType.LPArray)] double[] flatValues, 
    [MarshalAs(UnmanagedType.LPArray)] int[] subLengths, int totalCount);

static void Main(string[] args)
{
    List<double[]> lst = new List<double[]>();
    lst.Add(new double[] { 1.2, 1.3 });
    lst.Add(new double[] { 2.3, 2.4, 2.6 }); // 支持不同长度的子数组
    lst.Add(new double[] { 3.4, 3.5 });

    List<double> flatValues = new List<double>();
    List<int> subLengths = new List<int>();
    foreach (var arr in lst)
    {
        flatValues.AddRange(arr);
        subLengths.Add(arr.Length);
    }

    analysis(flatValues.ToArray(), subLengths.ToArray(), lst.Count);
}

C++端代码修改

#include <vector>
#include <iostream>

extern "C" __declspec(dllexport) void __cdecl analysis(double* flatValues, int* subLengths, int totalCount)
{
    using namespace std;
    vector<vector<double>> ind;
    int offset = 0;
    for (int i = 0; i < totalCount; i++)
    {
        int curLen = subLengths[i];
        ind.emplace_back(flatValues + offset, flatValues + offset + curLen);
        offset += curLen;
    }

    // 测试输出
    for (auto& subArr : ind)
    {
        for (auto val : subArr)
        {
            cout << val << " ";
        }
        cout << endl;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 14:48:00