将C结构移植到C#

twe*_*llt 2 c c# pinvoke

我正在将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;
Run Code Online (Sandbox Code Playgroud)

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

[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;
}
Run Code Online (Sandbox Code Playgroud)

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

  void         (*done)(void *thisobj);
  void          *e_cc;
Run Code Online (Sandbox Code Playgroud)

谢谢!

Dav*_*nan 5

在我们与代表会面之前,我怀疑您打包结构是错误的。这样做是非常不寻常的。仅当您#pragma在C代码中找到包时才这样做。

e_cc字段不是函数指针。这只是一个空指针。在C#中是IntPtr

pl成员是4个指针的数组。我不太确定它们包含的内容,但可以肯定地将其编组为:

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public IntPtr[] pl;
Run Code Online (Sandbox Code Playgroud)

这使您无需人工干预即可填充阵列或读取其内容。编组可能可以完成此操作,但是在不了解互操作程序的语义的情况下,我无法说出该如何做。

至于done,您应该在结构外部声明委托。像这样:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void doneDelegate(IntPtr thisobj);
Run Code Online (Sandbox Code Playgroud)

在这里,我假设调用约定是cdecl因为C代码中没有别的说法。

将所有内容放在一起:

[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;
}
Run Code Online (Sandbox Code Playgroud)