简体   繁体   中英

Convert Unsigned Char * to uint16_t *

I have unsigned char * data like below:

unsigned char * data = ...;
data[0]=0x24;
data[1]=0x8A;
data[2]=0x07;
data[3]=0x75;

I want to convert it to uint16_t with below code:

uint16_t *res= (uint16_t*)(data);

The output will be:

res[0]= 0x8A24; res[1]=0x7507 

But I want res become like this:

res[0]=0x248A; res[1]=0x0775;

How can I change my code?

If you were to use operating system's header, you have the ntohs and htons function that can swap the bytes.

Else, it's trivial to add:

template <T> T swap_endianness(T in) {
  unsigned char array[sizeof(in)] = {};
  std::memcpy(array, &in, sizeof(in));
  // Byte swap now
  for (size_t i = 0; i < sizeof(in)/2; i++) 
    std::swap(array[i], array[sizeof(in) - i - 1]);
  std::memcpy(&in, array, sizeof(in));
  return in;
}

Usage is:

uint16_t *res= (uint16_t*)(data); // This is undefined behavior. Use memcpy instead.
res[0] = swap_endianness(res[0]); // and so on

This only works for Plain Old Data type, such as uint64 , uint32 , uint16 , int64 , int32 , int16 , float , double .

As @KamilCuk pointed out, the like (uint16_t *)(data) might lead to issues if data happens not to be aligned at 16-bit boundary and will likely cause a memory access error when you'll dereference it on platfrom like ARM. The correct solution is to use memcpy like this:

uint16_t res[2];
std::memcpy(res, data, sizeof(res));
res[0] = swap_endianness(res[0]);
res[1] = swap_endianness(res[1]);

But I want res become like this:

How can I change my code?

It's just:

res[0] = data[0] << 8 | data[1];
res[1] = data[2] << 8 | data[3];

I want to convert it to uint16_t with below code:

 uint16_t *res= (uint16_t*)(data);

The output will be:

Such code will be invalid and dereferencing res results in undefined behavior. This is a strict alias violation and data may not be aligned to alignof(uint16_t) . If the compiler happens to generate code that doesn't result in a hard fault because of unaligned access, the result depends on the endianess of the target machine. But anyway, this is just undefined behavior.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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