如何正确地将C数组传递给C#? [英] How to properly pass a C array to C#?

查看:78
本文介绍了如何正确地将C数组传递给C#?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将某些数组从C ++传递给C#,它们被公开为C数组.这些数组是使用C#中的回调接收的.它们是在C ++端定义的:

I am trying to pass some arrays from C++ to C# and they are exposed as C arrays. These arrays are received using a callback in C#. This is how they are defined in the C++ side:

struct Image
{
    unsigned char* image_ptr;
    int rows;
    int cols;
};
typedef void(*CCallbackFn)(bool[], const char* [], Image[], Image, int length);

这就是我在C#中公开它们的方式:

And this is how I exposed them in C#:

[StructLayout(LayoutKind.Sequential)]
struct ImageStruct
{
   public IntPtr image_ptr;
   public int rows;
   public int cols;
}
delegate void CallbackDelegate( bool[] status, string[] id, ImageStruct[] img_face, ImageStruct img_org, int length);

经过编译,并且看起来工作正常,直到我注意到它仅返回每个数组的第一个元素!并且由于长度大于数组大小,程序将因索引超出范围错误而崩溃.

This compiled and seemed to work fine, until I noticed it only returns the first element of each array! and since the length is bigger than the array sizes, the program will crash with the index out of range error.

然后我尝试将它们更改为:

I then tried to change them to:

delegate void CallbackDelegate([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1)] bool[] status,
                               [param: MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[] id,
                               [param: MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPArray)] ImageStruct[] img_face,
                               ImageStruct img_org, int length);

此处提出的建议,但这也没有任何效果.仍然只返回第一个元素.我在这里想念什么?

as suggested in a similar question here, but this didn't have any effect either. Still only the first element is returned. What am I missing here?

推荐答案

封送处理程序需要知道非托管数组有多少个元素.数组本身不包含此信息.

The marshaler needs to know how many elements the unmanaged array has. The array itself does not contain this information.

该回调函数告诉您第5个参数 int length 中有多少个元素,该参数的索引从零开始,为 4 .因此,告诉要使用的封送拆封器此信息:

The callback tells you how many elements there are in the 5th argument, int length, which has the zero-based index of 4. So tell the marshaler to use this information:

delegate void CallbackDelegate(
  [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeParamIndex = 4)] bool[] status,
  [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr, SizeParamIndex = 4)] string[] id,
  [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] ImageStruct[] img_face,
  ImageStruct img_org,
  int length
);

这篇关于如何正确地将C数组传递给C#?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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