如何将 C 结构转换为托管 C# 等效项

How to translate a C struct to managed C# equivalent

我在 C 中有以下结构(示例):

typedef struct 
{
     int64      data_size;
     uint32      avgdelay;   
     int         esize;      
     void       *epayload;  
} stats_t;

托管 C# 等效项如下:

[StructLayout(LayoutKind.Sequential, Size = 4)]
public struct stats_t
{
    public Int64 datasize;

    public UInt32 avgdelay;

    public Int32 esize;

    public IntPtr epayload;

}

当在调用的回调委托中使用类型为 stats_t 的参数时,我发现有必要包含一个虚拟 UInt32 成员,以便能够通过委托调用回调,以保留字节模式回调签名

[StructLayout(LayoutKind.Sequential, Size = 4)]
public struct stats_t
{
    public Int64 datasize;

    public UInt32 avgdelay;

    public Int32 esize;

    public IntPtr epayload;

    /// dummy member for alignment
    public UInt32 dummy;

}

回调签名如下:

  int Callback_Proc( stats_t stats, void *user, int final, int error, int code);

回调委托具有以下签名:

  public delegate int Callback_Proc(stats_t stats, IntPtr user, Int32 final, Int32 error, Int32 code);

我想知道为什么需要虚拟成员才能使回调正常工作。没有虚拟的 final 的值被转移到 error,并且 error 的值被转移到 代码。 感谢您的理解,希望我的解释有意义。

那是因为 IntPtr 的大小。我假设你的 C++ 代码是为 64 位编译的,所以 C++ 代码期望的 void* 指针大小是 8 个字节,但是 .net 对 32 位有一个非常丑陋的偏好,如果你为 AnyCPU 编译,项目仍然有一个 ( stupid) flag named "Prefer 32 bits" on the compile options, 所以即使代码在 64 位机器上执行,它也会 运行 在 32 位导致指针长 4 个字节。

从项目中删除 "prefer 32 bits" 或显式编译为 x64,这应该可以解决您的问题。