2009-03-28 3 views
2

나는 어떤 packet.The 문제의 내용에 따라 CRC 체크 바이트를 생성하는 기능은 C#C#에서 포인터로 바이트 []를 할당하는 방법

C++ 코드를 C++에서 함수 번역에 있습니다 : 또한 LPBYTE으로 정의 될 수

unsigned char GenerateCheckByte(char* packet, int length, unsigned long seed) 
{ 
if(!packet) return 0; 
unsigned long checksum = 0xFFFFFFFF; 
length &= 0x7FFF; 
char* ptr = packet; 
unsigned long moddedseed = seed << 8; 
for(int i = 0; i < length; i++) 
    checksum = (checksum >> 8)^table[moddedseed + ((*(ptr++)^checksum) & 0xFF)]; 
unsigned char result = ((checksum>>24)&0xFF) + ((checksum>>8)&0xFF) + ((checksum>>16)&0xFF) + (checksum&0xFF); 
return result; 
} 

숯 * (패킷), 개념은 값 * 패킷 *의 PTR에 할당에게 할당하고시피 * PTR 바이트 배열 increases.Meaning하는 전달 된 그리고 포인터의 값을 증가시킴으로써 다음 바이트로 간다.

나는 C#에서 그것을 시도하고 여러 번 실패했습니다. 몇 가지 노력을 다해서 몇 가지 코드를 찾았지만 실행할 수 없습니다.

C# 코드

public static unsafe byte GenerateCheckByte(byte *packet, int length, UInt32 seed) 
    { 
     if (*packet == 0) 
     return 0; 
     UInt32 checksum = 0xFFFFFFFF; 
     length &= 0x7FFF; 
     byte *ptr = packet; 
     UInt32 moddedseed = seed << 8; 
     for (int i = 0; i < length; i++) 
      checksum = (checksum >> 8)^Table.table[moddedseed + ((*(ptr++)^checksum) & 0xFF)]; 
     byte result = (byte)(((checksum>>24)&0xFF) + ((checksum>>8)&0xFF) + ((checksum>>16)&0xFF) + (checksum&0xFF)); 
     return result; 
    } 

그것은 나쁜 보이지 않는,하지만 난

unsafe 
    { 
     packetBuffer[5] = Functions.GenerateCheckByte(&packetBuffer[0], 18, packet.seedCRC); 
    } 

오류를 호출 할 수 없습니다 : "당신은의 내부에 고정되지 않은 식의 주소를 취할 수 고정 된 문 이니셜 "

있습니다

C++ 및 C# 응용 프로그램에서 packetbuffer는 byte []입니다. packetBuffer = new byte [18];

답변

4

당신은 방법은 바이트 배열을 수용 할 수있다 :

public static unsafe byte GenerateCheckByte(byte[] packetArray, int length, UInt32 seed) 
{ 
    fixed(byte *packet = packetArray) 
    { 
     ... etc 
    } 
} 

것이 가능 뒤에 관리 인터페이스만큼 숨겨져 안전하지 않은 물건을 유지하는 것이 좋습니다.

그 다음은 쉬울 것이다 전화 :

packetBuffer[5] = Functions.GenerateCheckByte(packetBuffer, 18, ... 

사실, 어쨌든 배열에서 작동하도록 GenerateCheckByte를 작성하는 더 나은 것, 대신 unsafe 기술로 탐구의 :

public static unsafe byte GenerateCheckByte(byte[] packet, int length, UInt32 seed) 
{ 
    if (packet == null) 
     throw new ArgumentNullException("packet"); // the right way in C# 

    UInt32 checksum = 0xFFFFFFFF; 
    length &= 0x7FFF; 

    UInt32 moddedseed = seed << 8; 
    for (int i = 0; i < length; i++) 
     checksum = (checksum >> 8)^Table.table[moddedseed + ((packet[i]^checksum) & 0xFF)]; 
    byte result = (byte)(((checksum>>24)&0xFF) + ((checksum>>8)&0xFF) + ((checksum>>16)&0xFF) + (checksum&0xFF)); 
    return result; 
} 

쓰기 가장 간단하고 안전한 구현이 가능하며, 프로파일 링에서 병목 현상이 발견되면 포인터 만 사용해야합니다.

기존 C/C++를 C#으로 많이 변환하고 있습니까? 새로운 안전성/유지 보수성을 얻지 못한다면 약간의 요점이 있습니다. :)

+0

덕분에 훨씬 더 지금! –

1

바이트 배열을 메모리로 사용하여 '바이트로 사용'해야합니다.

byte checksum; 
fixed(byte* pPacketBuffer = packetBuffer) 
{ 
    checksum = Functions.GenerateCheckByte(pPacketBuffer, 18, packet.seedCRC) 
} 
packetBuffer[5] = checksum 

참고 문헌 :

2

당신은 전혀 안전하지 않은 코드를 사용할 필요가 없습니다. 함수에 바이트 배열을 보내면 포인터를 사용하지 않고도 액세스 할 수 있습니다.

나는 코드를 테스트하지 않은,하지만 결과는 아래와 같습니다 : 편집 코드에 대한

byte GenerateCheckByte(byte[] packet, ulong seed) { 
    if (packet == null) return 0; 
    int length = packet.Length & 0x7FFF; 
    ulong checksum = 0xFFFFFFFF; 
    ulong moddedseed = seed << 8; 
    for (int i = 0; i < length; i++) { 
      checksum = (checksum >> 8)^table[moddedseed + ((packet[i]^checksum) & 0xFF)]; 
    } 
    return (byte)(
     ((checksum >> 24) & 0xFF) + 
     ((checksum >> 16) & 0xFF) + 
     ((checksum >> 8) & 0xFF) + 
     (checksum & 0xFF) 
    ); 
} 
관련 문제