C # * и & оператор для указания на массив - PullRequest
0 голосов
/ 30 января 2019

Я перевожу функцию CRC C ++ в C #, и у меня возникают проблемы с передачей указателя на байтовый массив (без знака) в аргументе функции.В примере 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 # in выдает ошибку компилятора.

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

Аргумент 1: невозможно преобразовать из 'byte [] *' в 'byte []'.

Наилучший перегруженный метод соответствует для Program.ComputeChecksum (byte [], ushort) 'имеет несколько недопустимых аргументов

Является ли проблема в том, что функция C ++ использует ponter для массива unsigned char, и это невозможно в C #, что связано только с небезопасным использованием usinf?

1 Ответ

0 голосов
/ 30 января 2019

Прежде всего в 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 и добавление пакета System.Memory с помощью диспетчера пакетов Nuget.

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

И самое простое решение - добавление offsetи length помощники вашего метода

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