О реализации "GetBytes" в BitConverter

я обнаружил, что реализация GetBytes функция в .net framework-это что-то вроде:

public unsafe static byte[] GetBytes(int value)
{
   byte[] bytes = new byte[4];
   fixed(byte* b = bytes)
     *((int*)b) = value;
   return bytes;
}

Я не уверен, что понимаю все детали этих двух строк:

   fixed(byte* b = bytes)
     *((int*)b) = value;

может ли кто-нибудь дать более подробное объяснение здесь? И как я должен реализовать эту функцию в стандарт C++?

5 ответов


может ли кто-нибудь дать более подробное объяснение здесь?

на документация MSDN для fixed входит множество примеры и объяснение -- если этого недостаточно, то вам нужно будет уточнить, какую конкретную часть вы не понимаете.


и как я должен реализовать эту функцию в стандарт C++?

#include <cstring>
#include <vector>

std::vector<unsigned char> GetBytes(int value)
{
    std::vector<unsigned char> bytes(sizeof(int));
    std::memcpy(&bytes[0], &value, sizeof(int));
    return bytes;
}

Fixed говорит сборщику мусора не перемещать управляемый тип, чтобы вы могли получить доступ к этому типу со стандартными указателями.

В C++, если вы не используете C++ / CLI (т. е. не используете .NET), то вы можете просто использовать указатель размера байта (char) и цикл через байты во всем, что вы пытаетесь преобразовать.

просто надо знать порядок байтов...


First fixed должен использоваться, потому что мы хотим назначить указатель на управляемую переменную:

фиксированная инструкция предотвращает перемещение сборщика мусора подвижная переменная. Оператор fixed разрешен только в небезопасном контекст. Fixed также может использоваться для создания буферов фиксированного размера.

оператор fixed устанавливает указатель на управляемую переменную и " контакты" эта переменная во время выполнения инструкции. Без фиксированного, указатели для подвижных управляемых переменных было бы мало пользы, так как сбор мусора может перемещать переменные непредсказуемо. в Компилятор C# позволяет назначить указатель только на управляемую переменную в фиксированный оператор. Ref.

затем мы объявляем указатель на byte и назначаем начало массива байтов.

затем мы приведем указатель на byte к указателю на int, разыменуем его и назначим его переданному int.


функция создает массив байтов, содержащий те же двоичные данные, что и представление целочисленного value. В C++, это может быть достигнуто (для любого типа), например:

int value; // or any type!
unsigned char b[sizeof(int)];
unsigned char const * const p = reinterpret_cast<unsigned char const *>(&value);
std::copy(p, p + sizeof(int), b);

теперь b массив на столько байт, сколько размер типа int (или какой бы тип вы используете).

в C# вам нужно сказать fixed для получения необработанного указателя, так как обычно у вас нет необработанных указателей в C# из-за объектов, не имеющих фиксированного место в памяти-сборщик мусора может переместить их в любое время. fixed предотвращает это и фиксирует объект на месте, чтобы необработанный указатель мог иметь смысл.


вы можете реализовать GetBytes () для любого типа POD с помощью простого шаблона функции.

#include <vector>

template <typename T>
std::vector<unsigned char> GetBytes(T value)
{
    return std::vector<unsigned char>(reinterpret_cast<unsigned char*>(&value),
                                      reinterpret_cast<unsigned char*>(&value) + sizeof(value));
}