在Plan 9源代码中,我经常会找到这样的代码来读取具有明确定义的字节顺序的缓冲区中的序列化数据:
#include <stdint.h>
uint32_t le32read(uint8_t buf[static 4]) {
return (buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24);
}
Run Code Online (Sandbox Code Playgroud)
我希望gcc和clang都能将这段代码编译成像amd64上的这个程序集一样简单:
.global le32read
.type le32read,@function
le32read:
mov (%rdi),%eax
ret
.size le32read,.-le32read
Run Code Online (Sandbox Code Playgroud)
但是与我的期望相反,gcc和clang都没有认识到这种模式,而是产生了多次轮换的复杂装配.
有没有这种操作的习惯用法,既可以移植到所有C99实现,又可以跨实现产生良好的(如上面提到的那样)代码?
是否可以编写一个C包含an uint32_t并将其转换为大端序表示的宏,而不管目标系统是小端还是大端序,以便可以在编译时为常量求值?
我发现了一个问题:字节序转换,无论字节序如何,但是答案仅提供了功能。我的情况是我希望编译时表达式能够编写如下内容:
const uint32_t magic_number = BIGENDIAN32(0x12345678);
Run Code Online (Sandbox Code Playgroud) 我正在寻找在C++中解析二进制消息的任何示例库.大多数人要求读取二进制文件或在套接字中接收的数据,但我只需要解码一组二进制消息.有人提到了boost :: spirit,但我找不到合适的例子来满足我的需求.
例如:9A690C12E077033811FFDFFEF07F042C1CE0B704381E00B1FEFFF78004A92440
其中前8位是前同步码,接下来是6位msg ID(0到63之间的整数),接下来的212位是数据,最后24位是CRC24.
所以在这种情况下,msg 26,我必须从212个数据位获取这些数据:
编辑:我需要在位级操作,因此memcpy不是一个好的解决方案,因为它复制了许多字节.要获得第一个4位整数值,我应该从一个字节获得2位,从下一个字节获得另外2位,移位每一对并组成.我要求的是一种更优雅的方法来提取值,因为我有大约20种不同的消息,并希望达到一个通用的解决方案来解析它们的位级别.
等等.
你知道os可以轻松实现这个吗?
我还发现了其他使用static_cast的Q/A. 我用Google搜索,并且对于推荐这种方法的每个人,还有另一个关于端序的警告.由于我已经有了我的消息,我不知道这样的警告是否适用于我,或者只是用于套接字通信.
编辑:提升:dynamic_bitset看起来很有希望.任何使用它的帮助?
我在comp.lang.c ++上做了一个帖子,得到了这个
但这仍然不是答案.
我对二进制读操作有点困惑.
我试图用流函数读取二进制文件.这是商业程序(ANSYS)的结果文件,我知道文件的结构,至少从手册中知道.
该文件的结构为记录,程序以fortran编写.所以结构就像
记录长度(int)虚拟整数数据(可以是int,double)虚拟整数
第一个记录是100个整数块,其中这对应于上述表示中的数据.
如果我开始读取文件并读取第一个值,即记录长度(整数),我必须交换字节以获得正确的值100.
我不明白为什么我必须交换字节,因为这个文件是在同一台机器上生成的,它们应该使用相同的系统特定例程,所以这不应该是一个问题,但似乎并非如此.还有其他事情正在发生.我无法理解这一点.软件是否可以强制交换字节,我很难理解原因?
任何评论都表示赞赏.
这是一个天真的测试用例
int main () {
ifstream myfile;
char intBuffer[4];
myfile.open ("truss.rst", ios::binary);
myfile.read(intBuffer, sizeof(int));
//cout << *((int*)intBuffer) << endl;
// if I do not use this portion-
// I do not get what I want
char *cptr, tmp;
tmp = intBuffer[0];
intBuffer[0] = intBuffer[3];
intBuffer[3] = tmp;
tmp = intBuffer[1];
intBuffer[1] = intBuffer[2];
intBuffer[2] = tmp;
// -----------------------------
cout << *((int*)intBuffer) << endl;
myfile.close();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
最好的,美国
假设我有一个unsigned char(或byte)数组.我想从内存中取出array [1]和array [2]并将其转换为short int(2个字节).类似于联合的工作方式,但不是从第一个字节开始.
例:
#include <stdio.h>
void main()
{
unsigned char a[28];
unsigned short t;
a[0]=12;
a[1]=10;
a[2]=55;
t=(short) *(a+1);
printf("%i", t);
}
Run Code Online (Sandbox Code Playgroud)
我想要的是十进制值14090.或370Ah.
谢谢.
编辑:我忘了说,但大多数人都从我的例子中了解到,我正在研究一台小端机器.一个8位Atmel微控制器.
我期待着一种方法,我可以在没有隐式/显式转换,循环,切换,内置函数,宏的情况下找到字节序.我尝试过代码,但它使用显式转换.
int is_little_endian(){
int temp = 1;
return *(char *) temp;//Returns 1 if it's a little endian machine.
}
Run Code Online (Sandbox Code Playgroud)
[编辑]
它必须在不使用任何铸件的情况下完成.我找不到一个问题,我们可以在不投射和使用宏的情况下完成它.此处的隐式转换是指编译器自动转换.从char到int说.
c ×7
c++ ×3
endianness ×3
arrays ×1
binary ×1
binaryfiles ×1
c11 ×1
casting ×1
idioms ×1
objective-c ×1
optimization ×1
parsing ×1
pointers ×1