返回具有uint16_t值的偏移量
Returning an offset with uint16_t values
我在尝试重新解释数据以从消息中提取信息时遇到了一些困难。 我试图在这里重现问题。
我通过将它们从堆栈中弹出来接收一系列长整数(32 位)。 我需要将它们组装成 4 字(16 字节)数据包。我在下面重新创建的结构类似于给定数据包的第一个单词。 我遇到的困难在于,为了确定哪个单词是起始数据包,以及哪种类型的数据包是哪种类型的数据包,我需要能够读取结构的 s5 成员中数据的八进制值。
简而言之,对于每条消息,我需要将位 16-31 解释为 16 位整数,无论它是否跨越其他消息的位边界。
我本以为这将是一项容易得多的任务,但我似乎无法让它工作。 这是我尝试过的。我只是得到空值。
struct S
{
uint8_t s1 :8;
short s2 :2;
bool s3 :1;
int s4 :5;
uint16_t s5 :16;
};
int main() {
S s;
s.s1 = 3;
s.s2 = 2;
s.s3 = true;
s.s4 = 1;
s.s5 = 02050;
long l;
memcpy(&l, &s, sizeof(S));
std::deque<long> d;
d.push_back(l);
cout << *((uint16_t*)(&d.front()+2)) <<endl;
如果您已经从流中获得了long
值,为什么不直接使用位移呢?
假设数据是大端序的,你可以移开前 16 位,得到你的八进制值:
// 69733891 is the big-endian integral value represented by
// your posted sample data, so the octal value should be 02050,
// or as an int 1064
long l = 69733891;
uint16_t s5 = l >> 16; // shift off to get the high value (s5)
对于小端序(如您的帖子中所暗示的那样),您可以使用按位 AND:
uint16_t s5 = l & 0xFFFF;
为了快速比较为位移生成的程序集与指针别名,以下是 GCC 生成的内容(无优化):
为位移生成的程序集(请注意,SAR
是执行右位移的单个指令):
' uint16_t s5 = l >> 16;
mov rax,QWORD PTR [rbp-0x18]
sar rax,0x10
mov WORD PTR [rbp-0x1a],ax
为指针别名生成的程序集:
' uint16_t s5 = *((uint16_t*)&d[0]);
lea rax,[rbp-0x20]
mov esi,0x0
mov rdi,rax
call 4e <main+0x4e>
movzx eax,WORD PTR [rax] ' this is the "4e" address called
mov WORD PTR [rbp-0x12],ax
希望能有所帮助。
您在这里面临多个问题:
- 位域打包是实现定义的
- 将
long
重新解释为S*
或S&
违反了严格的别名规则
如果您坚持使用long
值,则必须使用有关编译器的假设,例如字节序,位打包顺序等,或者可能禁用字符串别名(我不建议这样做)。
溶液
如果l
是由struct S
实例的memcpy
创建的,则将值复制回struct S
的不同实例应得到完全相同的位布局。
因此,我们可以将deque
内的前端对象复制到struct S
的实例中,并检查它是否s5
成员:
long f = d.front();
S sf;
memcpy(&sf, &f, sizeof(sf));
std::cout << std::oct << sf.s5 << std::endl;
相关文章:
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 通过指针偏移量访问结构变量值
- 以线程安全的方式转换 C/C++ 中时区名称字符串的时区偏移量
- librdkafka:rd_kafka_assignment 返回分配分区的偏移量 -1001
- 是否通过向封闭对象的地址添加字节偏移量来访问子对象
- 向指针地址添加 20 个字节偏移量
- glMapBufferRange(..) 中的偏移量关系和 glDrawArraysInstanced(..) 中的第一
- 是否有与 C# Structs/StructLayout 等效的功能,C++中的字段偏移量?
- 我的 sumASCII 函数中的此偏移量是多少?
- boost::序列化中的派生类偏移量计算.有效吗?
- RedisGraph 语法错误在偏移量 8 靠近"创建"
- 胎面偏移量的时间复杂度?
- 如何从 c++ 中的给定标准输入中获取每个字符的偏移量?
- 编译器在构造函数中计算的成员偏移量不正确
- 使用基地址和偏移量获取变量的地址
- c++ 读取进程内存基址 + 偏移量不起作用
- 通过其在 C 中的偏移量调用函数
- ld:无效的字符串偏移量...对于".strtab"部分
- GDB 显示损坏的指令地址偏移量
- 读取文本文件时 seekg() 的奇怪偏移量