简体   繁体   English

如何从C ++中的整数缓冲区中提取4个字节的整数

[英]How to Extract 4 bytes of integer from a buffer of integers in c++

I have buffer/payload of integers where every 4 bytes is a field which i need to extract. 我有整数的缓冲区/有效载荷,其中每4个字节是我需要提取的字段。 I have a pointer pointing to the buffer. 我有一个指向缓冲区的指针。 Now I have to extract 4 bytes and assign it to variable until I reach the end of buffer. 现在,我必须提取4个字节并将其分配给变量,直到到达缓冲区末尾。 The pointer is uint8_t pointer to the buf and buf is a buffer object whose details are encapsulated. 指针是指向buf的uint8_t指针,而buf是其详细信息已封装的缓冲区对象。 What is the best and the most elegant way to do this? 最好和最优雅的方法是什么? I am coding in c++. 我在用C ++编写代码。 Any suggestions is appreciated. 任何建议表示赞赏。

You can do it as below using a C code: 您可以使用C代码如下进行操作:

int i = 0;
int value;
while(i < buffersize)
{
  value = 0;
  memcpy(&value, buffer, sizeof(int));
  //if the buffer is from network, then you may have to do a conversion from network order to host order here
  printf("%d", value);
  buffer = buffer + sizeof(int);
  i = i + sizeof(int);
}

I would recommend reading out the bytes one by one, and assembling the number "manually". 我建议一一读取字节,然后“手动”组装数字。 This requires you to be clear about the expected endianness, which is a good thing. 这要求您清楚预期的字节序,这是一件好事。 It also makes the code fine with any alignment requirements since all you read from the buffer is bytes. 由于您从缓冲区读取的全部都是字节,因此它也可以使代码符合任何对齐要求。

uint32_t extract_uint32_be(const uint8_t *buffer)
{
  const uint8_t b0 = buffer[0], b1 = buffer[1], b2 = buffer[2], b3 = buffer[3];

  return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
}

If the integers in your buffer are word-aligned, you could try: 如果缓冲区中的整数是字对齐的,则可以尝试:

const char* ptr; // this points to a position in a buffer
int value = reinterpret_cast<int*>(ptr);

Otherwise, perhaps safer and more preferable: 否则,也许更安全,更可取:

const char* ptr;
int value;
std::copy(ptr, ptr+sizeof(int), reinterpret_cast<char*>(value));

BTW: make sure you don't have a problem with endianess (ie both your machine and the machine that saved those ints must have the same endianess for this to work, otherwise you need to compensate). 顺便说一句:确保您没有字节序问题(即您的机器和保存这些int的机器必须具有相同的字节序才能正常工作,否则您需要进行补偿)。 You're relying on your specific implementation of C++ here. 您在这里依赖于C ++的特定实现。

assert(buf_bytes % 4 == 0);
std::vector<uint32_t> numbers(buf_bytes/4);
memcpy(&numbers[0], buf, buf_bytes);
if (need_byte_swap)
    std::for_each(numbers.begin(), numbers.end(), [](uint32_t &n){ntohl(n);});

转换为4字节整数和索引的数组。

Either read the bytes one at a time and shift /add them into the int or use memcpy to copy the bytes into a variable of the correct type. 一次读取一个字节并将其移位/添加到int中,或者使用memcpy将字节复制到正确类型的变量中。 std::copy might be acceptable too, I'm not sure of the rules for aliasing for that. std :: copy也可能是可以接受的,我不确定该别名的规则。

Casting to an array as suggest likely breaks the strict aliasing rules and therefore isn't guarenteed to work and is likely undefined behavour. 按照建议的方式强制转换为数组可能会破坏严格的别名规则,因此不能保证正常工作,并且可能是不确定的行为。

You can do it as below using a C code: 您可以使用C代码如下进行操作:

i points the buffer from where 4 bytes are to be read. 我指出要从中读取4个字节的缓冲区。

 read = (UInt32)((UInt8*)p_msg)[i++] << 24;
 read |= (UInt32)((UInt8*)p_msg)[i++] << 16;
 read |= (UInt32)((UInt8*)p_msg)[i++] << 8;
 read |= (UInt32)((UInt8*)p_msg)[i++];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM