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 wi开发者_运维知识库th 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.
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.
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;
}
精彩评论