C# * 和 & 运算符指向数组

标签 c# c++ arrays translate crc16

我正在将 C++ CRC 函数转换为 C#,但我在将指针传递给函数参数中的 (unsigned char) 字节数组时遇到了问题。在下面的 C++ 示例中

unsigned int CRC16_Calculation(unsigned char *buf, unsigned int len){
  unsigned int ix;
  unsigned int index;
  unsigned int crc = 0;

  for(ix=0; ix<len; ix++)
  {
    index = (high ^ buf[ix]) & 0x00FF;  
    crc = (low * 256) ^ Crc16Tbl[index];
  }
  return crc;}

我能够将此函数转换为 C#。

    public static unsafe ushort ComputeChecksum(byte[] buffer, ushort len)
{
    ushort index;
    ushort crc = 0;
    for (int i = 0; i < len; ++i)
    {
        index = (ushort)((low ^ buffer[i]) & 0x00FF);
        crc = (ushort)((high * 256) ^ table[index]);
    }

    return crc;
}

我需要使用C++中的函数如下:

crc= CRC16_Calculation(&Array[3], sizeof(Array)-3);

但是在 C# 中给我一个编译器错误。

ushort crc = ComputeChecksum(Array[3], (ushort)(Array.Length-3));

参数 1:无法从 'byte[]*' 转换为 'byte[]'。

“Program.ComputeChecksum(byte[], ushort)”的最佳重载方法匹配有一些无效参数

问题是 C++ 函数使用指向 unsigned char 数组的指针,而这在 C# 中是不可能的,仅当 usinf 不安全时才发生?

最佳答案

首先,在 C# 中,只将数组传递给一个没有长度的方法就足够了,因为 Array 类中包含 Length 属性。因此,您可以将方法重写为以下内容(unsafe 不是必需的,因为您没有在 C# 代码中使用指针)

public static ushort ComputeChecksum(byte[] buffer)
{
    ushort index;
    ushort crc = 0;
    for (int i = 0; i < buffer.Length; ++i) //using Length property
    {
        index = (ushort)((low ^ buffer[i]) & 0x00FF);
        crc = (ushort)((high * 256) ^ table[index]);
    }

    return crc;
}

而且您的问题几乎没有解决方案。第一个是使用 Linq。你可以这样调用你的方法

ushort crc = ComputeChecksum(arr.Skip(3).ToArray());

要使用Skip 方法,您需要添加using System.Linq;

第二种解决方案是使用 Span。它需要 Visual Studio 2017(或带有更新编译器的 2015),至少 .NET Framework 4.5 并使用 Nuget 包管理器添加 System.Memory 包。

var span = new Span<byte>(arr, 3, arr.Length - 3);
ushort crc = ComputeChecksum(span.ToArray());

最直接的解决方案是在您的方法中添加offsetlength 参数

public static ushort ComputeChecksum(byte[] buffer, int length, int offset)
{
    ushort index;
    ushort crc = 0;
    for (int i = offset; i < length; ++i)
    {
        index = (ushort)((low ^ buffer[i]) & 0x00FF);
        crc = (ushort)((high * 256) ^ table[index]);
    }

    return crc;
}

和用法

int offset = 3;
ushort crc = ComputeChecksum(arr, arr.Length - offset, offset);

关于C# * 和 & 运算符指向数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54442068/

相关文章:

c# - 使用 StringObjectIdGenerator 映射的 Id 在数据库中生成字符串 _id

c++11 按值捕获 lambda 产生错误的值

c# - 从 ASP.NET 将数据导出为 Excel 文件

c# - 如何从 ASP.NET 事件调用 C# 函数?

c++ - 如何将 std::vector<myClass*> 转换为 std::vector<const myClass* const>?

java - 该程序未记录第一个数组,设置为空 - Java

arrays - 如何在 TypeScript 中实例化一个包含字符串的数组?

c++ - 将对象的动态数组传递给函数

c# - 当不再引用订阅者时,如何实现取消订阅的事件?

c++ - 使用 boost::program_options 指定多个标志