Reputation: 2161
I'm Porting C code to C# and I have some doubts.
Consider this structure:
typedef struct
{
uint32_t w;
uint32_t h;
uint32_t f_cc;
uint32_t st;
unsigned char *pl[4];
int32_t strd[4];
void (*done)(void *thisobj);
void *e_cc;
uint32_t rsrvd2;
uint32_t rsrvd3;
} f_tt;
I've done this and it does not work (probably because it's wrong :-/ ):
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct f_tt
{
public uint w;
public uint h;
public uint f_cc;
public uint st;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public Byte[] pl;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public int[] strd;
public delegate void done(IntPtr thisobj);
public delegate void e_cc();
public uint rsrvd2;
public uint rsrvd3;
}
Can someone advise me how to do this i c#?
void (*done)(void *thisobj);
void *e_cc;
Thank you!
Upvotes: 3
Views: 10502
Reputation: 612804
Before we come to the delegates, I suspect that you are wrong to pack the struct. It's very unusual to do so. Only do that if you find the pack #pragma
in the C code.
The e_cc
field is not a function pointer. It's just a void pointer. In C# that is IntPtr
.
The pl
member is an array of 4 pointers. I'm not quite sure what they contain, but for sure you can marshal that like this:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public IntPtr[] pl;
That leaves you with manual intervention to populate the array, or read its contents. It's possible that could be done by the marshaller, but without knowing the semantics of the interop, I can't say how to do that.
As for done
, you should declare the delegate outside the struct. Like this:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void doneDelegate(IntPtr thisobj);
Here I am assuming that the calling convention is cdecl
since there's nothing in the C code to say otherwise.
Putting it all together you have:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void doneFunc(IntPtr thisobj);
[StructLayout(LayoutKind.Sequential)]
public struct f_tt
{
public uint w;
public uint h;
public uint f_cc;
public uint st;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public IntPtr[] pl;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public int[] strd;
public doneDelegate done;
public IntPtr e_cc;
public uint rsrvd2;
public uint rsrvd3;
}
Upvotes: 9