我知道C ++ 11有一些标准工具可以从未对齐的内存中获取整数值。怎样才能以更标准的方式写出这样的东西?
template <class R>
inline R get_unaligned_le(const unsigned char p[], const std::size_t s) {
R r = 0;
for (std::size_t i = 0; i < s; i++)
r |= (*p++ & 0xff) << (i * 8); // take the first 8-bits of the char
return r;
}
要获取以litte-endian顺序存储的值,您可以编写:
uint_least16_t value1 = get_unaligned_le<uint_least16_t > (&buffer[0], 2);
uint_least32_t value2 = get_unaligned_le<uint_least32_t > (&buffer[2], 4);
答案 0 :(得分:1)
与往常一样,创建所需的变量并按字节顺序填充:
#include <algorithm>
#include <type_traits>
template <typename R>
R get(unsigned char * p, std::size_t len = sizeof(R))
{
assert(len >= sizeof(R) && std::is_trivially_copyable<R>::value);
R result;
std::copy(p, p + sizeof(R), static_cast<unsigned char *>(&result));
return result;
}
这仅适用于普通的可复制类型,但如果您有其他地方的额外保证,您可以将它用于重要类型。
答案 1 :(得分:1)
积分值是如何进入未对齐的内存的?
如果他们是memcpy
,那么您可以使用memcpy
将其删除。
如果从文件或网络中读取它们,您必须知道它们
格式:它们是如何编写的。如果它们是四个字节
big-endian 2s补充(通常的网络格式),然后是东西
喜欢:
// Supposes native int is at least 32 bytes...
unsigned
getNetworkInt( unsigned char const* buffer )
{
return buffer[0] << 24
| buffer[1] << 16
| buffer[2] << 8
| buffer[3];
}
这适用于任何无符号类型,前提是您正在瞄准的类型 for至少与您输入的类型一样大。对于签名,这取决于 关于你想要的便携性。如果你所有的潜在目标 机器是2的补充,并将有一个整体类型 与输入类型相同的大小,然后您可以使用完全相同的代码 以上。如果您的本机是1位补码36位机器(例如 一个Unisys大型机),你正在阅读签名的网络格式整数 (32位2的补码),你需要一些额外的逻辑。