【发布时间】:2017-06-12 11:36:27
【问题描述】:
我在 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);
我想知道为什么需要虚拟成员才能使回调起作用。如果没有 dummy,final 的值会转移到 error,而 error 的值会转移到 code。 感谢您的理解,并希望我的解释是有道理的。
【问题讨论】:
-
您是否在相同位大小的操作系统和编译上同时编译和运行 C++ 和 C# 进程?乍一看,我可能会假设 C++ 进程是 64 位,而 C# 是 32 位,因此 IntPtr 将是 4 个字节,而 C++ void* 是 8 个字节。
-
也许您在一个 64 位系统上,需要 64 位 quanta 来构建结构?你有什么理由不只在 C# 中使用一个类吗?
-
C++ 和 C# 都使用相同的 x86 位数。还有一个针对 C++ 和 C# 代码的 x64 单独构建。
-
Size = 4太荒谬了,难以置信,结构比这大得多。我的水晶球说你实际上写了Pack = 4。不要那样做。
标签: c# callback delegates interop unmanaged