2009-03-27 4 views
1

C#을 구조에서 주문잘못된 구성원이 구조에서 패킷을두고 나는 TCP 클라이언트가

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

나는 구조에서 패킷을 넣어 사용하는 코드는 다음과 같습니다

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

이제 계속하기 전에이 프로젝트를 C++에서 C#으로 번역한다는 것을 말해야합니다.

문제이다 tPacket_5000_E의

마지막 3 부재 INT32있는 C++에서 DWORD 인 (너무 시도 UINT32). Int32의 세 멤버 앞에 오는 값은 C++의 값과 같습니다 (동일한 패킷을 C++ 및 C# 프로젝트에 모두 주입 함).

그러나 세 멤버의 값이 다릅니다.

C에서

++ 값은 (올바른) 위치 :

  1. seedCount : 0x00000079
  2. seedCRC : 0x000000D1이라는
  3. SeedSecurity :
  4. - [0] 0x548ac099
  5. -1 : 0x03c4d378
  6. - [2] : 0x292e9eab
  7. - [3] : 0x4eee5ee3
  8. - [4] : C에서 # 0x1071206e

값은 (잘못된) 위치 :

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

두 프로그램의 패킷은 동일한

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

구조체의 마지막 세 멤버가 다른 이유와 fi 방법 그들을 x?

미리 감사드립니다.

답변

11

나는 (당신의 문제의 근본 다음 32 비트 값이 워드로 정렬되어야하지 원인 세 바이트가

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

값이다, 코드의 당신의 두 세트를 추가하는 것을 기대 또는 추가하지 않음). C#을 나중에 값이 한 바이트 오프되도록 패딩 바이트를 삽입하여 ...

 
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     ] 

:

나는 다른 패킹이 같이 보일 것으로 기대합니다.

당신은 가능한 최소 공간을 사용해야하는, 당신의 구조체 정의 전에

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

를 사용하여 시도 할 수 있습니다.

Mastering Structs in C#에는 어떻게/왜 이런 일이 발생했는지에 대한 좋은 정보가 있습니다.

+0

@ 대니얼 L, 해결 방법을 제안 해 주시겠습니까? –

+0

@ 대니얼 L, 편집 해 주셔서 감사합니다. 지금 작동합니다! :) –

1

나는 그의 대답에서 올바른 경로에 Daniel L이 있다고 생각합니다.

플래그 뒤에 네 번째 바이트를 추가하려고합니다. 내 생각 엔 C++ 컴파일러가 워드 경계 값을 정렬하는 것입니다. 그것은 C# 버전을 "정렬"합니다.

+0

난 그냥 새 바이트를 public byte notneeded; 결과를 복어 [0] (다음 구성원)에 배치해야하는 값을 추가 한 값으로 이동되고 마지막 세 값은 여전히 ​​동일합니다. –

+0

Reed Copsey, 해결책이 작동하지 않았지만 도움을 주셔서 감사합니다. 그래서 답을 찾았습니다. Daniel L. 감사합니다. 빠른 지원에 감사드립니다. –

관련 문제