当前位置:  开发笔记 > 编程语言 > 正文

C#结构中的成员顺序不正确

如何解决《C#结构中的成员顺序不正确》经验,为你挑选了1个好方法。

我有一个TCP客户端,它将数据包放在一个结构中

using System.Runtime.InteropServices;

[StructLayoutAttribute(LayoutKind.Sequential)]
public struct tPacket_5000_E
{
    public Int16 size;
    public Int16 opcode;
    public byte securityCount;
    public byte securityCRC;
    public byte flag;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.I1)]
    public byte[] blowfish;
    public UInt32 seedCount;
    public UInt32 seedCRC;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 5, ArraySubType = UnmanagedType.I1)]
    public UInt32[] seedsecurity;
}

我用来将数据包放入结构中的代码是:

tPacket_5000_E packet = new tPacket_5000_E();
GCHandle pin = GCHandle.Alloc(data, GCHandleType.Pinned);
packet = (tPacket_5000_E)Marshal.PtrToStructure(pin.AddrOfPinnedObject(), typeof(tPacket_5000_E));
pin.Free();

现在,在我继续之前,我必须告诉你我正在将这个项目从C++转换为C#.

这就是问题:

tPacket_5000_E的最后3个成员是Int32(我也尝试过UInt32),这是C++中的DWORD.这三个成员之前的值( Int32)与C++中的值相同.(我在C++和C#项目中都注入相同的数据包).

但是,这三个成员有不同的价值观.

在C++中,值是(正确的):

    seedCount:0x00000079

    seedCRC:0X000000D1

    SeedSecurity:

    - [0]:0x548ac099

    - 1:0x03c4d378

    - [2]:0x292e9eab

    - [3]:0x4eee5ee3

    - [4]:0x1071206e

在C#中,值是(不正确):

    seedCount:0xd1000000

    seedCRC:0x99000000

    SeedSecurity:

    - [0]:0x78548ac0

    - 1:0xab03c4d3

    - [2]:0xe3292e9e

    - [3]:0x6e4eee5e

    - [4]:0x00107120

两个应用程序中的数据包是相同的

byte[] data = new byte[] {
0x25, 0x00, 0x00, 0x50, 0x00, 0x00, 0x0E, 0x10, 
0xCE, 0xEF, 0x47, 0xDA, 0xC3, 0xFE, 0xFF, 0x79, 
0x00, 0x00, 0x00, 0xD1, 0x00, 0x00, 0x00, 0x99, 
0xC0, 0x8A, 0x54, 0x78, 0xD3, 0xC4, 0x03, 0xAB, 
0x9E, 0x2E, 0x29, 0xE3, 0x5E, 0xEE, 0x4E, 0x6E, 
0x20, 0x71, 0x10};

点击这里查看更多信息

为什么结构中的最后三个成员是不同的以及如何解决它们?

提前致谢!



1> Daniel LeChe..:

我希望你的问题的根源是三个字节的值

public byte securityCount;
public byte securityCRC;
public byte flag;

导致下一个32位值不是字对齐的,并且您的两组代码以不同方式添加(或不添加)内部填充.

我希望不同的包装看起来像这样:

C++                                   C#
================================      ================================
[size          ][opcode        ]      [size          ][opcode        ]
[secCnt][secCrc][flag  ][blow0 ]      [secCnt][secCrc][flag  ][blow0 ]
[blow1 ][blow2 ][blow3 ][blow4 ]      [blow1 ][blow2 ][blow3 ][blow4 ]
[blow5 ][blow6 ][blow7 ][seedCou      [blow5 ][blow6 ][blow7 ]..PAD...
nt                     ][seedCRC      [seedCount                     ]
                       ][seedSec      [seedCRC                       ]
urity0                 ][seedSec      [seedSecurity0                 ]
urity1                 ][seedSec      [seedSecurity1                 ]
urity2                 ][seedSec      [seedSecurity2                 ]
urity3                 ][seedSec      [seedSecurity3                 ]
urity4                 ]              [seedSecurity4                 ]

...用C#插入一个填充字节,导致后面的值关闭一个字节.

你可以尝试使用

[StructLayout(LayoutKind.Sequential,Pack=1)]

在结构定义之前,应该使用尽可能少的空间.

掌握C#中的Structs有一些关于如何/为什么会发生这种情况的好信息.

推荐阅读
linjiabin43
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有