2009-03-27 26 views
1

ich einen TCP-Client haben, die ein Paket in einer Struktur setztfalsche Mitglieder in einer C# Struktur bestellen

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

Der Code verwende ich das Paket in der Struktur zu setzen ist:

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

Nun, bevor ich fortfahre, muss ich Ihnen sagen, dass ich dieses Projekt von C++ nach C# übersetze.

Dies ist das Problem:

Die letzten 3 Mitglieder tPacket_5000_E sind Int32 (i versucht UInt32 zu), die DWORD in C++ ist. Die Werte vor diesen drei Mitgliedern, die NICHT Int32 sind, sind gleich denen in C++. (Ich injiziere dasselbe Paket in C++ und C# -Projekt).

Diese drei Mitglieder haben jedoch unterschiedliche Werte.

in C++ sind die Werte (korrekte):

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

in C#, um die Werte (falsche):

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

das Paket in beiden Anwendungen ist gleich

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

Click here for further information

Warum die letzten drei Mitglieder in der Struktur sind anders und wie zu fi x sie?

Vielen Dank im Voraus!

Antwort

11

Ich würde erwarten, dass die Wurzel des Problems ist, dass die drei Byte

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

Werte lassen die nächsten 32-Bit-Werte nicht wortausgerichtet sein, und Ihre zwei Sätze von Code hinzufügen (oder (nicht hinzufügen) das interne Auffüllen anders.

Ich gehe davon aus, dass die verschiedenen Packungen in etwa so aussehen:

 
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     ] 

... mit C# ein Byte padding einfügen, die später Werte verursacht ein Byte aus sein.

können Sie versuchen,

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

vor Ihrer Struktur nach Definition, was möglich, die minimale Menge an Speicherplatz verwenden soll.

Mastering Structs in C# hat einige gute Informationen darüber, wie/warum das passiert.

+0

@Daniel L, Können Sie eine Lösung vorschlagen, um dies zu beheben? –

+0

@Daniel L, Danke für deine Bearbeitung - es funktioniert jetzt! :) –

1

Ich vermute, dass Daniel L in seiner Antwort auf dem richtigen Weg ist.

Ich würde versuchen, ein 4. Byte nach dem Flag hinzufügen. Meine Vermutung ist, dass Ihr C++ - Compiler die Werte auf Wortgrenzen ausrichtet. Das würde die C# -Version ebenfalls "ausrichten".

+0

Ich habe gerade ein neues Byte unter dem Flag hinzugefügt (public byte notneeded;) das Ergebnis: Der Wert, der bei blowfish [0] (das nächste Mitglied) platziert werden soll, wird auf den Wert i hinzugefügt und der letzte verschoben Drei Werte sind immer noch gleich. –

+0

Reed Copsey, Ihre Lösung hat nicht funktioniert, aber ich schätze Ihre Hilfe sehr, also habe ich auch Ihre Antwort ausgegraben! Ich fand es heraus, dank Daniel L. Vielen Dank für die schnelle Unterstützung. –

Verwandte Themen