C# 構造内のメンバーの順序が正しくありません
-
22-08-2019 - |
質問
パケットを構造体に入れる 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 です。これら 3 つのメンバーの前の値は、 ない Int32 は C++ のものと同じです (C++ と C# プロジェクトの両方に同じパケットを挿入します)。
しかし、この3人のメンバーはそれぞれ異なる価値観を持っています。
C++ では、値は (正しい):
- シード数:0x00000079
- シードCRC:0x000000d1
- シードセキュリティ:
- -[0]:0x548ac099
- -1:0x03c4d378
- -[2]:0x292e9eab
- -[3]:0x4eee5ee3
- -[4]:0x1071206e
C# では、値は次のとおりです(正しくない):
- シード数:0xd1000000
- シードCRC:0x99000000
- シードセキュリティ:
- -[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};
構造体の最後の 3 つのメンバーが異なる理由とその修正方法は何ですか?
前もって感謝します!
解決
私はあなたの問題の根本であることを期待する、3つのバイト値
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#は、後で値が1つのバイトオフさせるパディングのバイトを挿入している。
あなたが使用して試すことができます。
[StructLayout(LayoutKind.Sequential,Pack=1)]
の可能なスペースの最小量を使用する必要があり、あなたの構造体定義、前ます。
C#のの中に構造体をマスターする方法についていくつかの良い情報を持っています/なぜこれが起こっています。
他のヒント
私はダニエル・L には、右側にあると思われます彼の答えにトラックます。
私は、フラグの後に4バイト目を追加しようとするだろう。私の推測では、あなたのC ++コンパイラがワード境界に値を合わせていることです。それは、同様にC#バージョンを「揃える」でしょう。