6

我发现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++ 中实现这个功能?

4

6 回答 6

4

有人可以在这里提供更详细的解释吗?

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;
}
于 2011-12-30T01:31:32.187 回答
0

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

在 C++ 中,如果您不使用 C++/CLI(即不使用 .NET),那么您可以只使用字节大小的指针 (char) 并循环遍历您要转换的任何字节。

请注意字节顺序...

于 2011-12-30T01:31:30.987 回答
0

必须使用第一个固定的,因为我们要分配一个指向托管变量的指针:

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

固定语句设置一个指向托管变量的指针,并在语句执行期间“固定”该变量。如果没有固定,指向可移动托管变量的指针将几乎没有用处,因为垃圾收集可能会不可预测地重新定位变量。C# 编译器仅允许您在固定语句中分配指向托管变量的指针。 参考

然后我们声明一个指向字节的指针并分配给字节数组的开头。

然后,我们将指向 byte 的指针转换为指向 int 的指针,取消引用并将其分配给传入的 int。

于 2011-12-30T01:32:30.657 回答
0

该函数创建一个字节数组,其中包含与您的平台表示的整数相同的二进制数据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防止这种情况并将对象固定到位,以便原始指针有意义。

于 2011-12-30T01:33:00.563 回答
0

您可以使用简单的函数模板为任何 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));
}
于 2011-12-30T01:54:17.017 回答
0

这是一个 C++ 仅标头库,可能会有所帮助。

位转换器

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

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

于 2021-01-31T00:59:06.457 回答