不正确的编组:C#数组到C ++非托管数组 [英] Improper marshaling: C# array to a C++ unmanaged array

查看:298
本文介绍了不正确的编组: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());






参数,我不知道在哪里。然后:


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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆