О реализации "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));
}