2012-06-21 113 views
0

我有整数的缓冲区/有效载荷,其中每4个字节是我需要提取的字段。 我有一个指向缓冲区的指针。现在我必须提取4个字节并将其分配给变量,直到达到缓冲区末尾。 指针是uint8_t指向buf的指针,buf是其封装细节的缓冲区对象。 什么是最好的和最优雅的方式来做到这一点? 我在C++中编码。任何建议表示赞赏。如何从整数的缓冲区中提取4个字节的整数C++

+1

你的意思是你有一个整数或字节数组的数组,你要转换为整数? – Andrew

+0

uint8_t指向buf的指针。 buf一个缓冲区对象,而不是一个数组 – Nikhil

+0

什么是缓冲区对象呢? – Andrew

回答

1

如果你的缓冲区的整数是字对齐的,你可以尝试:

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

否则,或许更安全,更可取:

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

BTW:确保你没有存在问题(例如,您的机器和保存这些整数的机器必须具有相同的字节序才能工作,否则您需要进行补偿)。你在这里依赖于你特定的C++实现。

+0

假设如果担心endianess,你可以使用已建立的函数之一进行转换:'value = ntohl(*(reinterpret_cast (ptr)))'尽管我承认,我没有尝试过。 –

+0

'ntohl'和'htonl'用于在给定的机器和标准网络约定之间进行转换。如果数据可能来自保存在另一台计算机上的二进制文件,那么只有当保存者和读者一致使用它们时,这些数据才有用。 – Kos

+0

非常真实。我想,OP需要更多的信息。 –

0

投射到4字节整数和索引的数组。

+1

复制到适当对齐的内存缓冲区后。 – jxh

0

要么一次读取一个字节,要么将它们添加到int中,要么使用memcpy将字节复制到正确类型的变量中。 std :: copy也是可以接受的,我不确定那个别名的规则。

按照建议投射到数组可能会打破严格的别名规则,因此不能保证工作,并且可能是未定义的行为。

+0

别名允许在C和C++中使用'char *'进行别名。 – Kos

+0

不,您可以使用char *访问某些数据的字节,但不能反过来。 – jcoder

2

你可以做到这一点,如下用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); 
} 
1
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);}); 
1

我会建议读出字节一个接一个,和“手动”组装的数量。这要求你清楚预期的字节顺序,这是一件好事。由于您从缓冲区读取的所有内容都是字节,因此它还可以使代码更好地满足任何对齐要求。

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; 
} 
0

可以做到这一点,如下使用的C代码:

i指向从那里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++]; 
相关问题