strutture annidate in C # P / Invoke
Domanda
Sto cercando di mettere in una DLL non gestita che ha la seguente struttura:
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;
Questo è quello che sto usando sul lato 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;
}
La chiamata che sto facendo è specificato in questo modo:
ppr_error_type ppr_detect_objects (ppr_context_type context,
ppr_image_type image,
ppr_object_list_type *object_list);
Il mio C # chiamata simile a questo:
ObjectInfo info = new ObjectInfo();
int objOK = ppr_detect_objects(context, imagePtr, ref info);
So che il ppr_object_list_type si aspetta di riempire un array di oggetti. E so che C # ha problemi con gli array arbitray di oggetti nidificati. Stavo pensando che il modo in cui sto facendo che sarebbe tornato solo il primo (che è tutto mi interessa).
Tuttavia, quando lo chiamo in questo modo "num_oggetti" è compilati correttamente con un valore di 1. Il model_id è sbagliato (assomiglia ad un indirizzo di memoria) e tutto il resto è zero.
Ogni aiuto è apprezzato. Ho fatto un sacco di lavoro delle strutture di passaggio al codice unmanages, ma mai niente di lontanamente questo complesso.
Soluzione
ppr_object_list_type
contiene un puntatore per un ppr_object_type
, non un valore ppr_object_type
reale.
È necessario modificare ObjectInfo
a
[StructLayout(LayoutKind.Sequential)]
public struct ObjectInfo
{
public int numObjects;
public IntPtr objListPointer;
}
Per accedere ai valori ObjectType
, è necessario utilizzare i metodi nella Marshal classe.
Altri suggerimenti
Questo dovrebbe funzionare se vi interessa soltanto il primo elemento:
public struct ObjectInfo
{
public int numObjects;
[MarshalAs(UnmanagedType.LPArray, SizeConst = 1)]
public ObjectType[] objListPointer;
}