如何将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
相关产品推荐
相关产品推荐

