不正确的编组:C#数组到C ++非托管数组 [英] Improper marshaling: C# array to a C++ unmanaged array
问题描述
我有以下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());
参数,我不知道在哪里。然后:
There is an error in the marshaling of the second parameter, I don't know where. Then:
//C++ code
struct CInput {
double Time;
double Database[3650];
/*etc*/
}
int Example(CInput& ObjIn) {
return ObjIn.Database[0]; // just an example
}
如果我不小心,只指定SafeArray 在数据库编组我得到一个'读/写内存错误,可能已损坏'等。
If I'm not careful and specify only "SafeArray" in the Database marshaling I get a 'error in reading/writing memory, probably corrupt' etc.
如果数据库被封送为ByValArray一切都很好,正确显示。不幸的是,我得到一个内部大小的异常,因为我有很多数组的大小,因此我必须去指针 - 但任何与SizeArray将带来以下结果(刚刚发布的代码):
if "Database" was marshaled as ByValArray everything is fine, the values show up correctly. Unfortunately I get an internal size exception because I have many arrays of that size, therefore I have to go for pointers - but anything with "SizeArray" will bring the following results (with the code just posted):
(来自C ++):
Database[0] = **0**
Database[1..etc] = values of the next parameters in the struct marshaled with ByValArray.
我想我应该提到我需要从C#到C ++相同的结构,寻找任何花式。所以在结构中的数组>>>在结构中的数组
I think I should mention that I need the same identical structure from C# to C++, I'm not looking for anything fancy. So Array in a Struct >>> Array in a Struct.
任何对此的洞察将是非常有价值的。我一直在寻找几个小时,我还没有解决方案。
ANY insight in reference to this would be of great value. I have been looking for hours and I don't have yet a solution.
非常感谢。
推荐答案
我理解你的问题,你不能使用 ByValArray
和 SizeConst
因为你的真正的结构有大量的这样的数组,导致堆栈溢出。
As I understand your question, you can't use ByValArray
with SizeConst
because your real struct has a large number of such arrays which results in the stack overflowing.
你认为也许你需要使用指针在结构中,我同意您。
You opine that maybe you need to use pointers in your structs and I agree with you. Here is how to do it.
在C ++方面,您应该将每个数组声明为指向元素类型的指针:
On the C++ side you should declare each array as a pointer to the element type:
struct CInput {
double *array;
}
您还可以在结构中包含数组的长度,过多的硬编码常量。
You may also wish to include the length of the arrays in the struct to avoid excessive amounts of hard-coded constants.
所有的辛勤工作都发生在C#端。
All the hard work happens on the C# side.
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);
}
这篇关于不正确的编组:C#数组到C ++非托管数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!