C#P / Invoke中的嵌套结构

时间:2010-01-14 17:27:28

标签: c# interop pinvoke

我正在尝试调用具有以下结构的非托管DLL:

typedef struct
    {
      int num_objects;
      ppr_object_type *objects;
    } ppr_object_list_type;
ppr_coordinate_type;

typedef struct
{
  int model_id;
  ppr_coordinate_type position;
  float scale_factor;
  float size;
  ppr_rotation_type rotation;
  int nominal_width;
  int nominal_height;
  float confidence;
  int num_landmarks;
  ppr_landmark_type *landmarks;
} ppr_object_type;

typedef struct
{
  float x;
  float y;
} 

typedef struct
{
  float yaw;
  float pitch;
  float roll;
  ppr_precision_type precision;
} ppr_rotation_type;

这就是我在C#端使用的内容:

[StructLayout(LayoutKind.Sequential)]
    public struct ObjectInfo
    {
        public int numObjects;
        public ObjectType objListPointer;
    }

[StructLayout(LayoutKind.Sequential)]
    public struct ObjectType
    {
        int model_id;
        Coordinate position;
        float scale_factor;
        float size;
        Rotation rotation;
        int nominal_width;
        int nominal_height;
        float confidence;
        int num_landmarks;
        IntPtr landmarks;

    }
    [StructLayout(LayoutKind.Sequential)]
    public struct Coordinate
    {
        float x;
        float y;
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct Rotation
    {
        float yaw;
        float pitch;
        float roll;
        int precision;
    }

我正在进行的通话如下:

ppr_error_type ppr_detect_objects (ppr_context_type context,
                                   ppr_image_type image,
                                   ppr_object_list_type *object_list);

我的C#电话看起来像这样:

ObjectInfo info = new ObjectInfo();
int objOK = ppr_detect_objects(context, imagePtr, ref info);

我知道ppr_object_list_type希望填充一个对象数组。我知道C#在嵌套对象的任意数组中存在问题。我在想,我这样做的方式只会返回第一个(这就是我所关心的)。

然而,当我这样调用它时,“num_objects”被正确填充,值为1. model_id是错误的(看起来像一个内存地址),其他一切都是零。

感谢任何帮助。我已经做了很多工作,将结构传递给unmanage代码,但从来没有任何远程复杂的东西。

2 个答案:

答案 0 :(得分:1)

ppr_object_list_type包含ppr_object_type指针,而不是实际的ppr_object_type值。

您需要将ObjectInfo更改为

[StructLayout(LayoutKind.Sequential)]
public struct ObjectInfo
{
    public int numObjects;
    public IntPtr objListPointer;
}

要访问ObjectType值,您需要使用Marshal类中的方法。

答案 1 :(得分:0)

如果你只关心第一项,这应该有效:

public struct ObjectInfo
{
    public int numObjects;
    [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)]
    public ObjectType[] objListPointer;
}