我想用 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 后它不再工作的原因是什么?我感谢任何提示/帮助。
澄清一下,您最近也开始将 C 库编译为 64 位?这可能会更改结构上的默认打包,但可能不会。您是否在 C 代码中手动指定了对齐边界?你需要先澄清这个事实。C 结构现在打包是 8 个字节还是仍然是 4 个字节?还是设置为紧凑,字节对齐?
在 ConnectionMessage::P id 上的字段偏移量为 8 似乎意味着您认为 C 字段现在是 8 字节对齐的,因为它上面的字段显然只有 4 个字节宽。如果你是 8 字节对齐的,你不能在 12 或 44 处有偏移量,等等。如果是字节对齐或 4 字节对齐,将 Pid 偏移到 8 字节显然是错误的。在文本/连接消息上也有同样的故事。