Pregunta

Tengo un Cliente TCP,que pone un paquete en una estructura

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

El código que uso para poner el paquete en la estructura es:

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

Ahora,antes de continuar, debo decirle que estoy traduciendo este proyecto de C++ a C#.

Este es el problema:

El pasado 3 miembros de tPacket_5000_E son Int32(he intentado UInt32 demasiado),que es DWORD en C++.Los valores antes de los tres miembros,que son NO Int32,son iguales a los de C++.(Me inyecto mismo paquete en C++ y C# proyecto).

Sin embargo,los tres miembros tienen diferentes valores.

en C++ los valores son(correcto):

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

en C# los valores son(incorrecta):

  1. seedCount:0xd1000000
  2. seedCRC:0x99000000
  3. SeedSecurity:
  4. -[0]:0x78548ac0
  5. -1:0xab03c4d3
  6. -[2]:0xe3292e9e
  7. -[3]:0x6e4eee5e
  8. -[4]:0x00107120

El paquete en ambas aplicaciones es igual

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

Haga clic aquí para obtener más información

¿Por qué los tres últimos miembros en la estructura son diferentes y cómo solucionarlos?

Gracias de antemano!

¿Fue útil?

Solución

Yo esperaría que la raíz de su problema es que los tres valores de bytes

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

causar los siguientes valores de 32 bits no sean alineados por palabras, y sus dos conjuntos de código son la adición de (o no añadiendo) acolchado interno diferente.

espero que los diferentes envases tienen el siguiente aspecto:

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 # inserción de un byte de relleno que provoca posteriores valores sean un byte fuera.

Puedes probar a utilizar

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

antes de que su definición struct, que debe utilizar la mínima cantidad de espacio posible.

Dominar Las estructuras en C # tiene una buena información sobre cómo / por qué sucede esto.

Otros consejos

Daniel L está a la derecha realizar un seguimiento de su respuesta.

Me gustaría probar la adición de un cuarto byte después de la bandera. Mi conjetura es que el compilador de C ++ está alineando los valores en los límites de las palabras. Eso sería "alinear" la versión de C # también.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top