如何将C数组正确传递给C#?

问题描述 投票:0回答:1

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

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

这就是我在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);

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

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

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);

[在类似问题here中建议,但也没有任何作用。仍然只返回第一个元素。我在这里想念什么?

c# dllimport
1个回答
2
投票

封送拆收器需要知道非托管数组有多少个元素。数组本身不包含此信息。

回调告诉您第5个参数int length中有多少个元素,该参数具有从零开始的索引4。因此,tell封送处理程序可以使用此信息:

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
);
© www.soinside.com 2019 - 2024. All rights reserved.