Вложенные структуры в C# P/invoke
Вопрос
Я пытаюсь вызвать неуправляемый 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 ожидает заполнить массив объектов. И я знаю, что у# есть проблемы с арбитражными массивами вложенных объектов. Я думал, что то, как я делаю это, вернет только первый (это все, что меня волнует).
Однако, когда я называю это таким образом, «num_objects» правильно заполняется значением 1. Model_ID неверен (выглядит как адрес памяти), а все остальное - нули.
Любая помощь ценится. Я проделал много работы, передавая структуры, чтобы не управлять кодом, но никогда не что -либо отдаленно такого сложного.
Решение
ppr_object_list_type
содержит указатель в ppr_object_type
, не настоящий ppr_object_type
ценность.
Вам нужно изменить ObjectInfo
к
[StructLayout(LayoutKind.Sequential)]
public struct ObjectInfo
{
public int numObjects;
public IntPtr objListPointer;
}
Чтобы получить доступ к ObjectType
значения, вам нужно использовать методы в Маршал учебный класс.
Другие советы
Это должно работать, если вы заботитесь только о первом пункте:
public struct ObjectInfo
{
public int numObjects;
[MarshalAs(UnmanagedType.LPArray, SizeConst = 1)]
public ObjectType[] objListPointer;
}