どのように割り当てbyteバッファがダイレクトバッファとしてのポインタをクライアントまで、フルのC#

StackOverflow https://stackoverflow.com/questions/693710

  •  22-08-2019
  •  | 
  •  

質問

い機能を生成するCRCチェックのバイトのコンテンツの内容です。問題は、翻訳の機能をC++から、javascriptの名前空間にC#

C++のコード:

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

char*(パケット)として定義することもできLPBYTE、ということに割り当てられる値です*パケットが割り当てられ*ptrとして、*ptrが増加します。を意味するバイト配列として渡され、価値を高めるポインタで、次のバイトになります。

にしようとしていクライアントまで、フルの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);
  }

エラー:"きみのアドレスの固定化されていない表現内の決定初期化"

ご注意ください

packetbuffer両方のC++とC#の申請はbyte[]packetBuffer=新しいbyte[18];

役に立ちましたか?

解決

あなたは方法は、バイト配列を受け入れて作ることができます:

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 ++の多くを翻訳していますか?あなたはそこからいくつかの新しい安全性/保守性を取得しない限り、それを行う少しポイントがあります。 :)

他のヒント

あなたは全く危険なコードを使用する必要はありません。あなたが関数にバイト配列で送信した場合、それはポインタを使用せずにアクセスすることができます。

私は、コードをテストしていませんが、それはこのようなものである必要があります:

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

必要なものは"ピンのバイト配列にメモリとして使用してbyte*.

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

参考文献:

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top