将字符数组转换为整数(大端和小端)

Vas*_*asu 1 c endianness linux-kernel

我正在尝试将 char 数组转换为整数,然后我必须增加该整数(小端和大端)。

例子:

char ary[6 ] = { 01,02,03,04,05,06};
long int b=0; // 64 bits
Run Code Online (Sandbox Code Playgroud)

这个字符将存储在内存中

              address  0  1  2  3  4  5
              value   01 02 03 04 05 06   (big endian)
Edit :        value   01 02 03 04 05 06   (little endian)
Run Code Online (Sandbox Code Playgroud)

——

memcpy(&b, ary, 6); // will do copy in bigendian L->R
Run Code Online (Sandbox Code Playgroud)

这是它如何存储在内存中:

       01 02 03 04 05 06 00 00 // big endian increment will at MSByte
       01 02 03 04 05 06 00 00 // little endian increment at LSByte
Run Code Online (Sandbox Code Playgroud)

所以如果我们增加64位整数,期望值是01 02 03 04 05 07。但是字节序在这里是一个大问题,因为如果我们直接增加整数的值,它会产生一些错误的数字。对于大端,我们需要移动 b 中的值,然后对其进行增量。

对于小端,我们不能直接递增。(编辑:反向和公司)

我们可以将wrt复制到字节序吗?所以我们不需要担心轮班操作等等。

将字符数组复制为整数后,还有其他增加字符数组值的解决方案吗?

Linux内核中是否有任何API可以将wrt复制到endianess?

unw*_*ind 5

您需要阅读文档。此页面列出了以下内容:

__u64 le64_to_cpup(const __le64 *);
__le64 cpu_to_le64p(const __u64 *);
__u64 be64_to_cpup(const __be64 *);
__be64 cpu_to_be64p(const __u64 *);
Run Code Online (Sandbox Code Playgroud)

我相信它们足以做你想做的事。将数字转换为 CPU 格式,递增它,然后转换回来。


Lun*_*din 5

除非您希望字节数组表示更大的整数(这里似乎并非如此),否则字节序无关紧要。Endianess 仅适用于 16 位或更大的整数值。如果字符数组是 8 位整数数组,则字节顺序不适用。所以你所有的假设都是不正确的,char数组将始终存储为

  address  0  1  2  3  4  5
  value   01 02 03 04 05 06 
Run Code Online (Sandbox Code Playgroud)

不管字节序。

但是,如果您将数组 memcpy 为 a uint64_t,则字节顺序确实适用。对于大端机器,只需 memcpy() 即可获得预期格式的所有内容。对于小端,您必须反向复制数组,例如:

#include <stdio.h>
#include <stdint.h>

int main (void)
{
  uint8_t array[6] = {1,2,3,4,5,6}; 
  uint64_t x=0;

  for(size_t i=0; i<sizeof(uint64_t); i++)
  {
    const uint8_t bit_shifts = ( sizeof(uint64_t)-1-i ) * 8;
    x |= (uint64_t)array[i] << bit_shifts;
  }

  printf("%.16llX", x);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)