2

I am trying to call into an unmanaged DLL that has the following structure:

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;

This is what I am using on the C# side:

[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;
    }

The call I am making is specified like this:

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

My C# call looks like this:

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

I know that the ppr_object_list_type is expecting to fill in an array of objects. And I know C# has troubles with arbitray arrays of nested objects. I was thinking that the way I am doing it would return just the first one (which is all I care about).

However, when I call it this way "num_objects" is filled in correctly with a value of 1. The model_id is wrong (looks like a memory address) and everything else is zeros.

Any help is appreciated. I have done lots of work passing structures to unmanages code, but never anything remotely this complex.

2 Answers 2

1

ppr_object_list_type contains a pointer to a ppr_object_type, not an actual ppr_object_type value.

You need to change ObjectInfo to

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

To access the ObjectType values, you'll need to use the methods in the Marshal class.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. This was what I was missing. I did this: ObjectType foo = (ObjectType) Marshal.PtrToStructure(objPtr, typeof (ObjectType)); It works now. ad
0

This should work if you only care about the first item:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.