我正在研究memcache协议的实现,在某些点上,它使用64位整数值.这些值必须以"网络字节顺序"存储.
我希望有一些uint64_t htonll(uint64_t value)
功能可以进行更改,但不幸的是,如果它存在,我找不到它.
所以我有1或2个问题:
我想到了一个基本的实现,但我不知道如何在编译时检查字节序以使代码可移植.所以你的帮助非常受欢迎;)
谢谢.
这是我写的最终解决方案,感谢Brian的解决方案.
uint64_t htonll(uint64_t value)
{
// The answer is 42
static const int num = 42;
// Check the endianness
if (*reinterpret_cast<const char*>(&num) == num)
{
const uint32_t high_part = htonl(static_cast<uint32_t>(value >> 32));
const uint32_t low_part = htonl(static_cast<uint32_t>(value & 0xFFFFFFFFLL));
return (static_cast<uint64_t>(low_part) << 32) | high_part;
} else
{
return value;
}
}
Run Code Online (Sandbox Code Playgroud) 我们需要支持3个硬件平台--Windows(小端)和Linux嵌入式(大端和小端).我们的数据流依赖于它使用的机器,数据需要分解为位字段.
我想写一个宏(如果可能的话)来抽象出细节.在Linux上,我可以使用bswap_16
/ bswap_32
/ bswap_64
进行Little Endian转换.
但是,我在Visual C++中找不到这个包含.
两个平台(Windows和Linux)都有通用的内置功能吗?
如果没有,那么我可以在Visual C++中使用什么来进行字节交换(除了自己编写 - 希望一些机器优化内置)?
谢谢.
Visual Studio的定义_byteswap_uint64
和_byteswap_ulong
在stdlib.h
。
我是否正确地假设,这不是标准的并且不会在 Linux 或 Darwin 上编译?
有没有办法以跨平台的方式定义这些包含?
我正在用C编写Linux程序来分析嵌入式系统生成的核心文件.核心文件可能是小端(ARM)或大端(MIPS),分析它们的程序可能在小端主机(x86)或大端(PowerPC)上运行.
通过查看标题,我知道核心是LE还是BE.我宁愿我的程序并不需要知道它运行在主机是否很少或大端,我想使用一个API来处理对我来说.如果没有更好的选择,我想我会开始依赖#ifdef __BIG_ENDIAN__.
在Linux内核中,我们有cpu_to_le32等从原生字节排序转换为小端等.在用户空间中有htonl等,它从原生端转换为大端,但是我找不到本机到小端的等价物.
任何人都可以为用户空间建议合适的API吗?
编辑:为了清楚,我正在寻找一个已经知道我的CPU是大端还是小端的API,并相应地交换.我不想为#ifdefs乱丢我的代码.我不只是在寻找代码片段来交换字节; 谢谢你们,但那不是重点.
来自/usr/include/time.h:
/* Used by other time functions. */
struct tm
{
int tm_sec;. . . /* Seconds..[0-60] (1 leap second) */
int tm_min;. . . /* Minutes..[0-59] */
int tm_hour;. . . /* Hours.. [0-23] */
int tm_mday;. . . /* Day... [1-31] */
int tm_mon;. . . /* Month.. [0-11] */
int tm_year;. . . /* Year.- 1900. */
int tm_wday;. . . /* Day of week..[0-6] */
int tm_yday;. . . /* Days in year.[0-365].*/
int tm_isdst;.. . …
Run Code Online (Sandbox Code Playgroud) 我正在努力将系统从python转换为c ++.我需要能够在c ++中执行通常使用Python执行的操作struct.unpack
(将二进制字符串解释为数值).对于整数值,我可以使用以下数据类型来实现(某种程度)工作stdint.h
:
struct.unpack("i", str) ==> *(int32_t*) str; //str is a char* containing the data
Run Code Online (Sandbox Code Playgroud)
这适用于little-endian二进制字符串,但在big-endian二进制字符串上失败.基本上,我需要>
在struct.unpack中使用标签的等价物:
struct.unpack(">i", str) ==> ???
Run Code Online (Sandbox Code Playgroud)
请注意,如果有更好的方法,我会全力以赴.但是,我不能使用c ++ 11,也不能使用除Boost之外的任何第三方库.我还需要能够解释浮点数和双打数,就像在struct.unpack(">f", str)
和中一样struct.unpack(">d", str)
,但是当我解决这个问题时我会谈到它.
注意我应该指出,在这种情况下,我的机器的字节顺序是无关紧要的.我知道我在代码中收到的比特流总是大端的,这就是为什么我需要一个始终涵盖大端案例的解决方案.BoBTFish在评论中指出的文章似乎提供了一个解决方案.
当我编译以下程序时(我从C++ 中的 64 位 ntohl()获得的所有定义的代码?这似乎很合理):
\n\n#include <stdint.h>\n#if defined(__linux__)\n#include <endian.h> //htobe64,be64toh\n#include <arpa/inet.h> //ntohs, ntohl, htonl, htons\n#elif defined(__FreeBSD__) || defined(__NetBSD__)\n#include <sys/endian.h>\n#elif defined(__OpenBSD__)\n#include <sys/types.h>\n#define be16toh(x) betoh16(x)\n#define be32toh(x) betoh32(x)\n#define be64toh(x) betoh64(x)\n#endif\n\nint main()\n{\n int64_t i = 0x1212121234343434;\n int64_t j = be64toh(i);\n return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n使用以下命令编译它时出现链接错误(我正在运行 linux):
\n\ngcc -std=c99 endian_test.c -o endian\n
Run Code Online (Sandbox Code Playgroud)\n\n我收到的错误是:
\n\nuser@host ~/src/c $ gcc -std=c99 derp.c \nendian_test.c: In function \xe2\x80\x98main\xe2\x80\x99:\nendian_test.c:17:2: warning: implicit declaration of function \xe2\x80\x98be64toh\xe2\x80\x99 [-Wimplicit-function-declaration]\n int64_t j = be64toh(i);\n ^\n/tmp/ccYonfH4.o: In function `main\':\nendian_test.c:(.text+0x23): undefined reference to …
Run Code Online (Sandbox Code Playgroud) 我有一个字符数组和指向它的指针.我需要将第一个8Bytes(8字节的二进制值)添加到第二个8字节模2exp(64).我怎么能这样做?
我找到了解决方案.但做这些事情肯定不好(见代码).然而,将结果放在chars数组中会很好.
void init(const unsigned char *k) {
uint64_t *kp = k;
uint64_t sum = (*kp + *(kp+1)) % pow(2,64)
}
Run Code Online (Sandbox Code Playgroud)
感谢帮助
endianness ×6
c ×5
c++ ×4
htonl ×2
linux ×2
32bit-64bit ×1
64-bit ×1
compilation ×1
include ×1
linker ×1
pointers ×1
portability ×1
python ×1
visual-c++ ×1