不正确的编组:C#数组到C ++非托管数组

我有以下C#代码,其中包含结构定义(CInput),obj定义和init,以及对C ++(本机)DLL函数的调用(也是由我编写的)。

//C# code public struct CInput { [MarshalAsAttribute(UnmanagedType.R8)] public double Time; [MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_R8)] public double[] Database; /* other similar fields*/ } CInput Inputs = new CInput(); /* init of Inputs fields*/ int bfr = Example(ref Inputs); //'Example' being the C++ DLL call Messagebox.Show(bfr.ToString()); 

编组第二个参数时出错,我不知道在哪里。 然后:

 //C++ code struct CInput { double Time; double Database[3650]; /*etc*/ } int Example(CInput& ObjIn) { return ObjIn.Database[0]; // just an example } 

如果我不小心并且在数据库封送中仅指定“SafeArray”,则会出现“读/写内存错误,可能已损坏”等。

如果“数据库”被封送为ByValArray一切正常,则值会正确显示。 不幸的是我得到了一个内部大小exception,因为我有很多那个大小的数组,因此我必须去指针 – 但是任何带有“SizeArray”的东西都会带来以下结果(代码刚刚发布):

(来自C ++):

 Database[0] = **0** Database[1..etc] = values of the next parameters in the struct marshaled with ByValArray. 

我想我应该提到我需要从C#到C ++的相同结构,我不是在寻找任何花哨的东西。 因此,结构中的结构>>>数组中的数组。

任何有关这方面的见解都具有重要价值。 我一直在找几个小时,我还没有解决方案。

提前谢谢了。

正如我理解你的问题,你不能将ByValArrayByValArray一起使用,因为你的真实结构有大量这样的数组导致堆栈溢出。

你认为也许你需要在你的结构中使用指针,我同意你的看法。 这是怎么做的。

在C ++方面,您应该将每个数组声明为指向元素类型的指针:

 struct CInput { double *array; } 

您可能还希望在结构中包含数组的长度,以避免过多的硬编码常量。

所有艰苦的工作都发生在C#方面。

 public struct CInput { public IntPtr array; } ... double[] theArray = new double[3650]; CInput input = new CInput(); input.array = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double))*theArray.Length); try { Marshal.Copy(theArray, 0, input.array, theArray.Length); //call your C++ function here } finally { Marshal.FreeHGlobal(input.array); } 
 public struct CInput  
 {    
    公共双倍时间;    
     [MarshalAs(UnmanagedType.ByValArray,SizeConst = 3650)] 
     public double []数据库;
 }       

 CInput Inputs = new CInput();  
 int bfr =示例(ref输入);

编辑。 如果需要动态分配数据库数组,则应更改C ++和C#代码。 在C ++中,数据库应定义为double *,并且需要在某处添加数组长度。 在C#中,数据库应声明为IntPtr,并使用Marshal.AllocHGlobal方法进行分配。 请根据您的要求更正C ++结构,然后根据此修复C#代码。