Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C语言中将64位无符号整数前后转换为字符缓冲区_C_String_64 Bit - Fatal编程技术网

在C语言中将64位无符号整数前后转换为字符缓冲区

在C语言中将64位无符号整数前后转换为字符缓冲区,c,string,64-bit,C,String,64 Bit,我的目标是通过以网络字节顺序的64位无符号整数开头的网络发送数据报。因此,首先我使用宏将数字转换为big-endian: #define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32)) #define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0x

我的目标是通过以网络字节顺序的64位无符号整数开头的网络发送数据报。因此,首先我使用宏将数字转换为big-endian:

#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
#define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
当我

a = 1494157850
htonll(a) = 1876329069679738880 ==> ntohll(htonll(a)) = 1494157850 
**** seriializing PRIu64 value = 1876329069679738880
bufer[0] = 1a
bufer[1] = a
bufer[2] = f
bufer[3] = 59
bufer[4] = 0
bufer[5] = 0
bufer[6] = 0
bufer[7] = 0
*********
*** deserializing buffer:
bufer[0] = 1a
bufer[1] = a
bufer[2] = f
bufer[3] = 59
bufer[4] = 0
bufer[5] = 0
bufer[6] = 0
bufer[7] = 0
===> res = 436866905
c = 6417359100811673600

似乎缓冲区没有捕获更大的数字…

您的序列化程序本质上是

unsigned char *serialize_u64(unsigned char *buffer, uint64_t value)
{
    buffer[7] = value & 0xFF;
    value >>= 8;
    buffer[6] = value & 0xFF;
    value >>= 8;
    buffer[5] = value & 0xFF;
    value >>= 8;
    buffer[4] = value & 0xFF;
    value >>= 8;
    buffer[3] = value & 0xFF;
    value >>= 8;
    buffer[2] = value & 0xFF;
    value >>= 8;
    buffer[1] = value & 0xFF;
    value >>= 8;
    buffer[0] = value & 0xFF;
    return buffer + 8;
}
从本机字节顺序序列化为网络字节顺序;不需要宏

因此,看起来OP的
serialize_uint64()
应该可以正常工作。只是根本不应该使用字节顺序宏

OP的
反序列化uint64()
应在移位之前将
缓冲区[i]
强制转换为
(uint64\u t)
,以确保移位结果为64位。就个人而言,我更喜欢将反序列化程序编写为

unsigned char *serialize_u64(unsigned char *buffer, uint64_t *valueptr)
{
    uint64_t value = buffer[0];
    value <<= 8;
    value |= buffer[1];
    value <<= 8;
    value |= buffer[2];
    value <<= 8;
    value |= buffer[3];
    value <<= 8;
    value |= buffer[4];
    value <<= 8;
    value |= buffer[5];
    value <<= 8;
    value |= buffer[6];
    value <<= 8;
    value |= buffer[7];
    *valueptr = value;
    return buffer + 8;
}
unsigned char*serialize_u64(unsigned char*buffer,uint64\u t*valueptr)
{
uint64_t值=缓冲区[0];

值编辑:它在32位时工作得很好,直到
2147483647
,但在
2147483648
时崩溃,强制转换到
uint64\u t
有帮助-非常感谢!但是在字节顺序宏上-如果我想让它可移植并且我不知道运行机器的尾端是什么,我需要以某种方式区分它-正确吗或者我遗漏了什么?@micsza:是的,你遗漏了什么。正如我所解释的,显示的代码将
值从/转换为本机字节顺序到/从网络字节顺序。本机字节顺序是什么并不重要。代码本身是完全可移植的。@micsza:至于不需要字节顺序转换的确切原因,我们需要看一看t涉及的数学。在网络字节顺序中,值的第一个字节是最重要的一个;对于64位值,它包含第56位到第63位,包括第56位到第63位。函数实现的数学是,使用位移位和掩蔽直接从64位值中提取这个和其他字节值。本机字节顺序无关,因为数学是d64位值上的1完全不依赖于本机字节顺序。
a = 1494157850
htonll(a) = 1876329069679738880 ==> ntohll(htonll(a)) = 1494157850 
**** seriializing PRIu64 value = 1876329069679738880
bufer[0] = 1a
bufer[1] = a
bufer[2] = f
bufer[3] = 59
bufer[4] = 0
bufer[5] = 0
bufer[6] = 0
bufer[7] = 0
*********
*** deserializing buffer:
bufer[0] = 1a
bufer[1] = a
bufer[2] = f
bufer[3] = 59
bufer[4] = 0
bufer[5] = 0
bufer[6] = 0
bufer[7] = 0
===> res = 436866905
c = 6417359100811673600
unsigned char *serialize_u64(unsigned char *buffer, uint64_t value)
{
    buffer[7] = value & 0xFF;
    value >>= 8;
    buffer[6] = value & 0xFF;
    value >>= 8;
    buffer[5] = value & 0xFF;
    value >>= 8;
    buffer[4] = value & 0xFF;
    value >>= 8;
    buffer[3] = value & 0xFF;
    value >>= 8;
    buffer[2] = value & 0xFF;
    value >>= 8;
    buffer[1] = value & 0xFF;
    value >>= 8;
    buffer[0] = value & 0xFF;
    return buffer + 8;
}
unsigned char *serialize_u64(unsigned char *buffer, uint64_t *valueptr)
{
    uint64_t value = buffer[0];
    value <<= 8;
    value |= buffer[1];
    value <<= 8;
    value |= buffer[2];
    value <<= 8;
    value |= buffer[3];
    value <<= 8;
    value |= buffer[4];
    value <<= 8;
    value |= buffer[5];
    value <<= 8;
    value |= buffer[6];
    value <<= 8;
    value |= buffer[7];
    *valueptr = value;
    return buffer + 8;
}