Pergunta

Eu tenho um TCP cliente, o que coloca um pacote em uma estrutura

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

O código que eu uso para colocar o pacote na estrutura é a seguinte:

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

Agora, antes de continuar, devo dizer-lhe que eu estou traduzindo este projecto de C ++ para C #.

Este é o problema:

Os últimos 3 membros da tPacket_5000_E são Int32 (i tentou UInt32 também), que é DWORD em C ++. Os valores antes que esses três membros, que são não Int32, são iguais aos de C ++. (I injetar mesmo pacote em C ++ e C # projeto).

No entanto, esses três membros têm valores diferentes.

em C ++ são os valores ( correcta ):

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

em C # os valores são ( incorreta ):

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

O pacote em ambas as aplicaçõ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};

Clique aqui para obter mais informações

Por que os três últimos membros da estrutura são diferentes e como corrigi-los?

Agradecemos antecipadamente!

Foi útil?

Solução

Eu esperaria que a raiz do problema é que os três valores de byte

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

causa os valores de 32 bits próximos não ser alinhados palavra, e seus dois conjuntos de código está adicionando (ou não adição) estofamento interno diferente.

Espero que as diferentes embalagens algo parecido com isto:

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                 ]

... com C # inserção de um byte de preenchimento que faz com que os valores mais tarde a ser um byte off.

Você pode tentar usar

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

Antes de sua definição struct, que deve usar a quantidade mínima de espaço possível.

Mastering Structs em C # tem algumas boas informações sobre como / por que isso acontece.

Outras dicas

Eu suspeito que Daniel L está à direita acompanhar em sua resposta.

Gostaria de tentar adicionar um quarto byte após a bandeira. Meu palpite é que seu compilador C ++ é alinhar os valores sobre os limites de palavra. Que iria "alinhar" a versão C # também.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top