2

我正在将 C 代码移植到 C#,但我有一些疑问。

考虑这个结构:

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;

我已经这样做了,但它不起作用(可能是因为它是错误的 :-/ ):

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

有人可以告诉我如何做这个 ic# 吗?

  void         (*done)(void *thisobj);
  void          *e_cc;

谢谢!

4

1 回答 1

7

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;
}
于 2013-04-17T16:28:10.543 回答