将C ++例程转换为C#,主要是指针

时间:2013-11-11 21:06:09

标签: c# c++

我主要是一名C ++程序员,但在业余时间,我正试图加快C#的速度。我有以下C ++函数,我想转换 -

#define COMPUTE_CRC32(cp,crc) (crc32lookup_table[((unsigned long)crc^(unsigned char)cp)&0xff]^(((unsigned long)crc>>8)&0x00FFFFFF))

unsigned long ComputeCRC32::Update(const void* ptrBytes, long numBytes)
{
    const unsigned char* ptr_data = (const unsigned char*) ptrBytes;

    while ( --numBytes >= 0 )
    {
        unsigned char data_byte = *ptr_data++ ; 

        m_ulCRC = COMPUTE_CRC32( data_byte, m_ulCRC );
    }

    return m_ulCRC;
}

我知道有很多方法可以做到这一点,但我想看看最好的方法是做什么。这是我到目前为止创造的 -

public uint Update(object ptrBytes, int numBytes)
{
    byte * ptr_data = (byte) ptrBytes;

    while (--numBytes >= 0)
    {
        byte data_byte = *ptr_data++;

        m_ulCRC = (GlobalMembersComputeCRC32.crc32lookup_table[((uint)m_ulCRC ^ (byte)data_byte) & 0xff] ^ (((uint)m_ulCRC >> 8) & 0x00FFFFFF));
    }

    return m_ulCRC;
}

转换指针的最佳方法是什么?有没有更好的方法在C#中重写它?

2 个答案:

答案 0 :(得分:2)

C#是一种具有指针的语言,但也有引用(和references are not necessarily addresses)。 C#中的byte[]等数组是表示在C ++中可能使用指针的常用方法。

要使用指针,请使用unsafe。如果你在思考C#,人们往往会避免使用unsafe,因为它通常是“不安全的”;而运行时则强制执行检查以避免数组中的缓冲区溢出等问题。相反,Crc32的伪代码可能是:

public uint Crc32(byte[] data) {
  uint result;
  for (int i= 0; i < data.Length; i++) {
    byte data_byte = data[i];
    result = doCrc(...stuff with data_byte...);
  }
  return result;
}

请注意,for循环使用data.Length作为其限制检查(ref:Eric Gunnerson: Efficiency of iteration over arrays),因为这可以通过JIT针对数组长度进行优化。如果使用单独的长度参数则不能,因此应避免这种情况(或者如果所需的迭代次数可能小于数组长度,则应与长度结合使用)。

答案 1 :(得分:0)

这些指针没有做任何棘手的事情。它们只是数组迭代器。

public uint Update( byte[] ptrBytes, int numBytes )
{
    for( int i = 0; i < numBytes; i++ )
    {
        byte data_byte = ptr_data[i];
        m_ulCRC = ...
    }

    return m_ulCRC;
}