当前位置:  开发笔记 > 编程语言 > 正文

如何在C#中将byte []分配为指针

如何解决《如何在C#中将byte[]分配为指针》经验,为你挑选了1个好方法。

我有一个根据任何数据包的内容生成CRC校验字节的函数,问题是将函数从C ++转换为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 *(p​​acket)也可以定义为LPBYTE,其思想是将分配给* packet的值分配给* 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);
  }

错误:“您只能在固定的语句初始化程序中使用未固定表达式的地址”

请注意

在C ++和C#应用程序中,packetbuffer均为byte [] packetBuffer = new byte [18];



1> Daniel Earwi..:

您可以使该方法接受字节数组:

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#?除非您从中获得一些新的安全性/可维护性,否则这样做毫无意义。:)

推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有