i membri non corretti ordine in una struttura C#
-
22-08-2019 - |
Domanda
Ho un Client TCP,che mette un pacchetto in una struttura
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;
}
Il codice che uso per mettere il pacchetto nella struttura è:
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();
Ora,prima di continuare devo dirti che sto traducendo questo progetto da C++ a C#.
Il problema è questo:
Gli ultimi 3 membri di tPacket_5000_E sono Int32(ho provato UInt32 troppo),che è DWORD in C++.I valori prima di quelle tre membri,che sono NON Int32,sono uguali a quelli in C++.(Io iniettare lo stesso pacchetto in C++ e C# progetto).
Tuttavia,quei tre membri hanno valori diversi.
in C++ i valori sono(corretto):
- seedCount:0x00000079
- seedCRC:0x000000d1
- SeedSecurity:
- -[0]:0x548ac099
- -1:0x03c4d378
- -[2]:0x292e9eab
- -[3]:0x4eee5ee3
- -[4]:0x1071206e
in C# i valori sono(errata):
- seedCount:0xd1000000
- seedCRC:0x99000000
- SeedSecurity:
- -[0]:0x78548ac0
- -1:0xab03c4d3
- -[2]:0xe3292e9e
- -[3]:0x6e4eee5e
- -[4]:0x00107120
Il pacchetto in entrambe le applicazioni è uguale
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};
Clicca qui per maggiori informazioni
Perché gli ultimi tre membri della struttura sono diversi e come risolverli?
Grazie in anticipo!
Soluzione
Mi sarei aspettato che la radice del problema è che i tre valori di byte
public byte securityCount;
public byte securityCRC;
public byte flag;
causa prossima valori a 32 bit non essere di parola-allineati, e con i due set di codice aggiunta (o non l'aggiunta imbottitura interna in modo diverso.
Mi aspetto che i diversi imballaggi immediati di contenuto simile a questo:
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 ]
...con C# inserimento di un byte di padding, che provoca poi i valori per essere un byte off.
Si può provare a utilizzare
[StructLayout(LayoutKind.Sequential,Pack=1)]
prima struct definizione, che dovrebbe utilizzare la quantità minima di spazio possibile.
Padroneggiare le Strutture in C# ha alcune buone informazioni su come e perché questo accade.
Altri suggerimenti
Ho il sospetto che Daniel L è sulla giusta strada per la sua risposta.
Vorrei provare ad aggiungere un 4 ° byte dopo la bandiera.La mia ipotesi è che il compilatore C++ è di allineare i valori limiti di word.Che sarebbe "allineare" la versione C# e.