About the implementation of "GetBytes" in BitConverter

I found that the implementation of the GetBytes function in the .net structure looks something like this:

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

I'm not sure I understand the full details of these two lines:

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

Can someone provide a more detailed explanation here? And how do I implement this function in standard C ++?

+6
source share
5 answers

Can someone provide a more detailed explanation here?

The MSDN documentation for fixed contains numerous examples and explanations - if this is not enough, then you will need to clarify the specific part that you do not understand.


And how do I implement this function in standard 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; } 
+4
source

It is fixed that the garbage collector does not move the managed type so that you can access this type with standard pointers.

In C ++, if you are not using C ++ / CLI (i.e. you are not using .NET), you can simply use the byte size indicator (char) and iterate over the bytes in what you are trying to convert.

Just be aware of the preface ...

0
source

The first fixed should be used because we want to assign a pointer to a managed variable:

The fixed statement prevents the garbage collector from moving the movable variable. A fixed statement is only allowed in an unsafe context. Fixed can also be used to create buffers of a fixed size.

A fixed statement sets a pointer to a managed variable and "contacts" this variable during the execution of an instruction. Without a fixed, pointers to movable managed variables will be of little use, since garbage collection can move variables unpredictably. The C # Compiler allows you to assign a pointer to a managed variable in a fixed statement. Link

Then we declare a pointer to a byte and assign the beginning of an array of bytes.

Then we point the byte to the pointer to the int, play it out and assign the passed int to it.

0
source

The function creates an array of bytes that contains the same binary data as your platform representation of the integer value . In C ++, this can be achieved (for any type indeed) as follows:

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

Now b is an array with as many bytes as the size of type int (or whatever type you use).

In C #, you need to say fixed to get a raw pointer, since you usually don’t have raw pointers to C # because of objects that do not have a fixed location in memory - the garbage collector can move them at any time. fixed prevents this and fixes the object in place, so the original pointer may make sense.

0
source

You can implement GetBytes () for any type of POD with a simple function template.

 #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)); } 
0
source

Source: https://habr.com/ru/post/904717/


All Articles