关于GetBytes"在BitConverter中实现

本文关键字:BitConverter 实现 GetBytes quot 关于 | 更新日期: 2023-09-27 18:19:14

我发现GetBytes函数在。net框架中的实现是这样的:

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++中实现这个函数?

关于GetBytes"在BitConverter中实现

谁能在这里提供更详细的解释?

fixed的MSDN文档提供了许多示例和解释—如果这还不够,那么您需要澄清您不理解的特定部分。


我应该如何在标准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;
}

固定告诉垃圾收集器不移动托管类型,以便您可以使用标准指针访问该类型。

在c++中,如果你不使用c++/CLI(即不使用。net),那么你可以使用字节大小的指针(char)并在你试图转换的任何字节中循环。

第一个fixed必须使用,因为我们想要将指针分配给托管变量:

fixed语句防止垃圾回收器重新定位可移动的变量。固定语句只允许在不安全的上下文。Fixed也可以用来创建固定大小的缓冲区。

fixed语句设置了一个指向托管变量的指针和"pins"该变量在语句执行期间。没有固定的,指向可移动托管变量的指针几乎没有用处,因为垃圾收集可能无法预测地重新定位变量。的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防止了这种情况,并将对象固定在适当的位置,因此原始指针可以有意义。

您可以使用一个简单的函数模板实现任何POD类型的GetBytes()。

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

这是一个c++头文件库,可能会有所帮助。

BitConverter

在c++中实现GetBytes函数的思想很直接:根据指定的布局计算值的每个字节。例如,假设我们需要获取一个16位无符号整数的字节数。我们可以将该值除以256得到第一个字节,并将余数作为第二个字节。

对于浮点数,算法稍微复杂一些。我们需要获取数字的符号、指数和尾数,并将它们编码为字节。见https://en.wikipedia.org/wiki/Double-precision_floating-point_format