membros incorrectas por ordem de uma estrutura C #
-
22-08-2019 - |
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 (
- seedCount: 0x00000079
- seedCRC: 0x000000D1
- SeedSecurity:
- - [0]: 0x548ac099
- - 1 : 0x03c4d378
- - [2]: 0x292e9eab
- - [3]: 0x4eee5ee3
- - [4]: ??0x1071206e
em C # os valores são ( incorreta ??strong>):
- seedCount: 0xd1000000
- seedCRC: 0x99000000
- SeedSecurity:
- - [0]: 0x78548ac0
- - 1 : 0xab03c4d3
- - [2]: 0xe3292e9e
- - [3]: 0x6e4eee5e
- - [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!
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.