我想用c#整理以下c结构。
struct ConnectionMessage
{
static const size_t MESSAGE_MAX_PATH = 260;
uint32_t version;
uint64_t pid;
char machineName[32];
char executablePath[MESSAGE_MAX_PATH];
};
struct TextMessage
{
static const size_t TEXT_SIZE = 256;
uint64_t timestamp;
uint32_t severity;
char module[32];
char channel[32];
char message[TEXT_SIZE];
};
struct RawLogMessage
{
uint32_t type;
union
{
ConnectionMessage connection;
TextMessage text;
};
};
在将C#程序集更改为x64之前,我过去使用的结构都可以正常工作。
这些是结构:
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct TextMessage
{
[FieldOffset(0), MarshalAs(UnmanagedType.U8)]
public UInt64 Timestamp;
[FieldOffset(8), MarshalAs(UnmanagedType.U4)]
public LogSeverity Severity;
[FieldOffset(12), MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string Module;
[FieldOffset(44), MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string Channel;
[FieldOffset(76), MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string Message;
public override string ToString()
{
return String.Format("{0} {1} {2} {3} {4}", this.Timestamp, this.Severity, this.Module, this.Channel, this.Message);
}
}
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct ConnectionMessage
{
[FieldOffset(0)]
public UInt32 Version;
[FieldOffset(8)]
public UInt32 Pid;
public override string ToString()
{
return String.Format("{0} {1}", this.Version, this.Pid);
}
}
[StructLayout(LayoutKind.Explicit, Pack = 0)]
public struct RawLogMessage
{
[FieldOffset(0), MarshalAs(UnmanagedType.U4)]
public MessageType Type;
[FieldOffset(8)]
public TextMessage TextMessage;
[FieldOffset(8)]
public ConnectionMessage ConnectionMessage;
}
处理该问题的正确方法是什么?将C#随意更改为x64后,它不再起作用的原因是什么?感谢您的提示/帮助。
答案 0 :(得分:1)
为澄清起见,您最近也开始将C库也编译为64位吗?那可能已经改变了结构上的默认包装,但是可能没有改变。您是否在C代码中手动指定了对齐边界?您需要先澄清这一事实。 C struct包装现在是8个字节还是4个字节?还是设置得紧凑,字节对齐?
在ConnectionMessage :: Pid上字段偏移为8似乎暗示您认为C字段现在是8字节对齐的,因为它上方的字段显然只有4字节宽。而且,如果您是8字节对齐的,则不能有12或44的偏移量,依此类推。如果是字节对齐或4字节对齐的,则将Pid偏移为8字节显然是错误的。关于Text / ConnectionMessage也是如此。