简体   繁体   English

如何正确地将无符号字符数组转换为 uint32_t

[英]How to properly convert an unsigned char array into an uint32_t

So, I'm trying to convert an array of unsigned char s into an uint32_t , but keep getting different results each time:因此,我正在尝试将unsigned char数组转换为uint32_t ,但每次都会得到不同的结果:

unsigned char buffer[] = {0x80, 0x00, 0x00, 0x00};;
uint32_t num = (uint32_t*)&buffer;

Now, I keep getting this warning:现在,我不断收到此警告:

warning: initialization makes integer from pointer without a cast警告:初始化使 integer 从没有强制转换的指针

When I change num to *num i don't get that warning, but that's not actually the real problem ( UPDATE: well, those might be related now that I think of it.), because every time I run the code there is different results .当我将num更改为*num时,我没有收到该警告,但这实际上不是真正的问题(更新:好吧,现在我想到这些可能是相关的。),因为每次我运行代码时都有不同结果 Secondly the num , once it's cast properly, should be 128 , but If I need to change the endianness of the buffer I could manage to do that myself, I think .其次num ,一旦正确转换,应该是128 ,但是如果我需要更改缓冲区的字节顺序,我可以自己设法做到这一点,我认为.

Thanks!谢谢!

Did you try this?你试过这个吗?

num = (uint32_t)buffer[0] << 24 |
      (uint32_t)buffer[1] << 16 |
      (uint32_t)buffer[2] << 8  |
      (uint32_t)buffer[3];

This way you control endianness and whatnot.这样你就可以控制字节顺序等等。

It's really not safe to cast a char pointer and interpret it as anything bigger.投射一个char指针并将其解释为更大的东西真的不安全。 Some machines expect pointers to integers to be aligned.一些机器期望指向整数的指针是对齐的。

cnicutar's answer is the best assuming you want a particular fixed endianness. cnicutar 的答案是最好的假设你想要一个特定的固定字节序。 If you want host endian, try:如果您想要主机端,请尝试:

uint32_t num;
memcpy(&num, buffer, 4);

or apply ntohl to cnicutar's answer.或将ntohl应用于 cnicutar 的答案。 Any method based on type punning is wrong and dangerous.任何基于类型双关语的方法都是错误和危险的。

First, you want to say num = *(uint32_t *)&buffer首先,你想说num = *(uint32_t *)&buffer

To change endianness, you can use a call like bswap_32 (in linux, byteswap.h) or OSSwapInt64 (in osx, libkern/OSByteOrder.h)要更改字节顺序,您可以使用 bswap_32(在 linux,byteswap.h 中)或 OSSwapInt64(在 osx,libkern/OSByteOrder.h 中)之类的调用

The warning was issued because &buffer yields a pointer to pointer.发出警告是因为&buffer产生一个指向指针的指针。 Even without the reference operator & the warning wouldn't have disappeared because the casting changes only the pointer type.即使没有引用运算符&警告也不会消失,因为转换仅更改指针类型。 The pointer is further converted to integer and therefore the warning.指针进一步转换为 integer 并因此发出警告。

If endianness is not important, the obvious solution seems to me如果字节序不重要,那么在我看来,显而易见的解决方案

unsigned char buffer[] = {0x80, 0x00, 0x00, 0x00};
uint32_t num = *(uint32_t *)buffer;

which means dereferencing the casted pointer to the char array.这意味着取消对 char 数组的强制转换指针的引用。

Borrowing from @ Mr. R.借用@ R 先生。 above, my approach for converting a 3 byte big endian unsigned char array within a structure to a little endian unsigned int...以上,我将结构中的 3 字节大端无符号字符数组转换为小端无符号整数的方法...

struct mystruct {
  int stuff;
  int stuff2;
  unsigned char x[3]    // big endian
} 
mystruct z;
unsigned int y  // little endian

memcpy(&y, z->x, 3);
y=be32toh(y<<8);`

Assuming it's the same endianess a union would the best option.假设它是相同的字节序,工会将是最好的选择。

union
{
    uint32_t u32;
    float flt;  
    uin8_T bytes[4];

} converter;

// Use of the above union // 使用上述联合

converter.bytes = your_byte_array;
uint32_t u32_output = converter.u32;
float float_output = converter.flt;

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

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