我有这样的C结构......
struct icmp_prefixopt {
u_int8_t icmpopt_type;
u_int8_t icmpopt_len;
u_int8_t prefixlen;
u_int8_t lflag:1;
u_int8_t aflag:1;
u_int8_t reserved:6;
};
我在同一个模块中为这样的成员提供了值 -
popt= (struct icmp_prefixopt *)
malloc(sizeof(struct icmp_prefixopt));
popt->icmpopt_type = 3;
popt->icmpopt_len = 4;
popt->prefixlen = (u_int8_t)strtoul(arg, (char **)NULL, 0);
arg = index(arg, '+');
if (arg) {
++arg;
popt->lflag = ((u_int8_t)strtoul(arg, (char **)NULL, 0))&1;
}
arg = index(arg, '+');
if (arg) {
++arg;
popt->aflag = ((u_int8_t)strtoul(arg, (char **)NULL, 0))&1;
}
arg = index(arg, '+');
if (arg) {
++arg;
popt->reserved = 32; //((u_int8_t)strtoul(arg, (char **)NULL, 0))<<2;
}
其中arg是传递给该模块的命令行参数。
现在以十六进制格式执行后查看结构的内容 - &gt;
03 04 20 81
icmpopt_type: seems fine
icmpopt_len: seems fine
prefixlen: seems fine
但其构成字节中的其他3个字段的位看起来相反 -
lflag:1; aflag:1; reserved:6
所以应该是 - 10100000=A0
但实际上它们是=>81=10000001
它给我带来了很多问题......
小端/大端有什么关系吗?
如果是,8位的htonl和htons等函数的对应部分。
如果不是,可能是什么问题或者我完全误解了什么?
什么是最好的方法?修改结构中这些字段的顺序
本身或在这里应用一些有点操作符和位移位?
命令行提供的输入 -
32+1+0+32
这个最后的32在这里没有任何意义,因为我已经在模块中修复了32个用于测试。 虽然我的实际目的也需要考虑这个领域。
请尽快通过任何替代方法帮助我。
提前完成。
修改
这是我需要创建的实际结构,并且随着创建,需要为用户做出规定,通过GUI为所有字段指定值。 (现在只能通过linux命令行)。
我想我现在已经让问题更加清晰了,但如果还需要更多信息,我会很乐意添加。
答案 0 :(得分:5)
编译器如何选择打包位字段完全取决于实现。它不一定与字节序有任何关系。
htnol
(和类似的)不适用于位字段。如果您需要保证订单,则需要自己手动打包uint8_t
。例如:
struct icmp_prefixopt {
u_int8_t icmpopt_type;
u_int8_t icmpopt_len;
u_int8_t prefixlen;
u_int8_t stuff;
}
...
popt->stuff = (lflag << 7) | (aflag << 6);
当然,在实践中,你应该使用合理的#define
而不是魔术数字(6和7)。你可以决定将它包装在一堆setter和getter函数中。