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):

  1. seedCount:0x00000079
  2. seedCRC:0x000000d1
  3. SeedSecurity:
  4. -[0]:0x548ac099
  5. -1:0x03c4d378
  6. -[2]:0x292e9eab
  7. -[3]:0x4eee5ee3
  8. -[4]:0x1071206e

in C# i valori sono(errata):

  1. seedCount:0xd1000000
  2. seedCRC:0x99000000
  3. SeedSecurity:
  4. -[0]:0x78548ac0
  5. -1:0xab03c4d3
  6. -[2]:0xe3292e9e
  7. -[3]:0x6e4eee5e
  8. -[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!

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top