Question

J'ai un client TCP qui place un paquet dans une structure

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;
}

Le code que j'utilise pour mettre le paquet dans la structure est :

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();

Maintenant, avant de continuer, je dois vous dire que je traduis ce projet de C++ vers C#.

C'est le problème:

Les 3 derniers membres du tPacket_5000_E sont Int32 (j'ai aussi essayé UInt32), qui est DWORD en C++.Les valeurs devant ces trois membres, qui sont PAS Int32, sont égaux à ceux de C++. (J'injecte le même paquet dans les projets C++ et C#).

Cependant, ces trois membres ont des valeurs différentes.

en C++, les valeurs sont (correct):

  1. nombre de graines : 0x00000079
  2. graineCRC : 0x000000d1
  3. Sécurité des semences :
  4. -[0]:0x548ac099
  5. -1:0x03c4d378
  6. -[2]:0x292e9eab
  7. -[3]:0x4eee5ee3
  8. -[4]:0x1071206e

en C#, les valeurs sont(Incorrect):

  1. nombre de graines : 0xd1000000
  2. graineCRC : 0x99000000
  3. Sécurité des semences :
  4. -[0] :0x78548ac0
  5. -1:0xab03c4d3
  6. -[2] :0xe3292e9e
  7. -[3] :0x6e4eee5e
  8. -[4] :0x00107120

Le paquet dans les deux applications est égal

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};

Cliquez ici pour plus d'informations

Pourquoi les trois derniers membres de la structure sont différents et comment les corriger ?

Merci d'avance!

Était-ce utile?

La solution

Je m'attendrais à ce que la racine de votre problème soit que les valeurs de trois octets

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

font que les valeurs de 32 bits suivantes ne sont pas alignées sur les mots et que vos deux ensembles de codes ajoutent (ou n'ajoutent pas) un remplissage interne différemment.

Je m'attends à ce que les différents emballages ressemblent à ceci :

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                 ]

...avec C# insérant un octet de remplissage, ce qui entraîne un décalage d'un octet des valeurs ultérieures.

Vous pouvez essayer d'utiliser

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

avant la définition de votre structure, qui doit utiliser le minimum d'espace possible.

Maîtriser les structures en C# a de bonnes informations sur comment/pourquoi cela se produit.

Autres conseils

Je soupçonne que Daniel L. est sur la bonne voie dans sa réponse.

J'essaierais d'ajouter un 4ème octet après le drapeau.Je suppose que votre compilateur C++ aligne les valeurs sur les limites des mots.Cela "alignerait" également la version C#.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top