处理字段偏移量C#C++;
我想用c#对下面的c结构进行marshall 在我将C#assembly更改为x64之前,我在过去使用的结构工作得很好 以下是结构:处理字段偏移量C#C++;,c#,marshalling,C#,Marshalling,我想用c#对下面的c结构进行marshall 在我将C#assembly更改为x64之前,我在过去使用的结构工作得很好 以下是结构: [StructLayout(LayoutKind.Explicit, Pack = 1)] public struct TextMessage { [FieldOffset(0), MarshalAs(UnmanagedType.U8)] public UInt64 Timestamp; [FieldOffset(8), MarshalAs
[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#assembly更改为x64后,它不再工作的原因是什么?非常感谢您的提示/帮助。为了澄清,您最近也开始编译64位的C库了?这可能会更改结构上的默认打包,但可能不会。您是否在C代码中手动指定了对齐边界?你需要先澄清这个事实。C结构现在是8字节还是4字节?还是将其设置为紧密打包,以对齐字节
ConnectionMessage::Pid上的字段偏移量为8似乎意味着您认为C字段现在是8字节对齐的,因为它上面的字段显然只有4字节宽。如果是8字节对齐,则偏移量不能为12或44,等等。如果是字节对齐或4字节对齐,则将Pid偏移为8字节显然是错误的。文本/连接消息上的相同故事。可能重复感谢!上述代码适用于32位C#代码。将C++部分更改为32/x64并不重要。两者都有效。如果我尝试将C#客户机更改为x64,就会出现错误。有没有一种简单的方法来确定结构是如何打包/对齐的?我还需要使用LayoutKind.Explicit吗?或者除了union,Sequential还能工作吗?用64位C DLL运行32位C#应用程序是行不通的;它甚至不会加载DLL。使用32位C DLL运行64位C#应用程序时,情况也是如此。如果您看到的是不同的行为,那么您的DLL选择就有错误。至于确定C代码对齐方式,您需要查看
pragma pack
和((packed))
的代码,并检查pack struct
参数的编译器参数。这是一种客户机/服务器体系结构。服务器已关闭源代码。我一直在使用的c结构来自另一个客户端,我正试图将它移植到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;
}