我发现.net框架中GetBytes
函数的实现类似于:
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 ++中实现这个功能?
答案 0 :(得分:4)
有人可以在这里提供更详细的解释吗?
MSDN documentation for 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;
}
答案 1 :(得分:0)
Fixed告诉垃圾收集器不要移动托管类型,以便您可以使用标准指针访问该类型。
在C ++中,如果您不使用C ++ / CLI(即不使用.NET),那么您可以使用字节大小的指针(char)并在您尝试转换的任何内容中循环遍历字节。 / p>
请注意字节序......
答案 2 :(得分:0)
首先必须使用fixed,因为我们想要指定一个指向托管变量的指针:
fixed语句阻止垃圾收集器重定位 可变量。固定语句只允许不安全 上下文。 Fixed也可用于创建固定大小的缓冲区。
fixed语句设置指向托管变量和“引脚”的指针 在执行语句期间的那个变量。没有固定, 从那以后,指向可移动托管变量的指针几乎没用 垃圾收集可以无法预测地重定位变量。的的 C#编译器只允许您指定一个指向托管变量的指针 固定声明。 Ref。
然后我们声明一个指向byte的指针并分配给字节数组的开头。
然后,我们将指向byte的指针转换为指向int的指针,取消引用它并将其分配给传入的int。
答案 3 :(得分: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
可以防止这种情况,并将对象固定到位,这样原始指针才有意义。
答案 4 :(得分: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));
}
答案 5 :(得分:0)
这里是一个仅包含 C++ 头文件的库,可能会有所帮助。
在 C++ 中实现 GetBytes
函数的想法很简单:根据指定的布局计算值的每个字节。例如,假设我们需要以 big endian 获取无符号 16 位整数的字节。我们可以将值除以 256 得到第一个字节,并将余数作为第二个字节。
对于浮点数,算法稍微复杂一些。我们需要获取数字的符号、指数和尾数,并将它们编码为字节。见https://en.wikipedia.org/wiki/Double-precision_floating-point_format