Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
处理字段偏移量C#C++;_C#_Marshalling - Fatal编程技术网

处理字段偏移量C#C++;

处理字段偏移量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

我想用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(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;
}