Tôi có cấu trúc C như thế này ...
cấu trúc icmp_prefixopt {
u_int8_t icmpopt_type;
u_int8_t icpopt_len;
tiền tố u_int8_t;
u_int8_t lflag:1;
u_int8_t gắn cờ:1;
u_int8_t dành riêng:6;
};
và tôi đã cung cấp giá trị cho thành viên như thế này trong cùng một mô-đun -
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 = chỉ mục(arg, '+');
nếu (arg) {
++ đối số;
popt->lfag = ((u_int8_t)strtoul(arg, (char **)NULL, 0))&1;
}
arg = chỉ mục(arg, '+');
nếu (arg) {
++ đối số;
popt->aflag = ((u_int8_t)strtoul(arg, (char **)NULL, 0))&1;
}
arg = chỉ mục(arg, '+');
nếu (arg) {
++ đối số;
popt->reserved = 32; //((u_int8_t)strtoul(arg, (char **)NULL, 0))<<2;
}
trong đó arg là các đối số dòng lệnh được truyền cho mô-đun này.
Bây giờ hãy xem nội dung của cấu trúc sau thực thi ở định dạng thập lục phân ->
03 04 20 81
icpopt_type: có vẻ ổn
icpopt_len: có vẻ ổn
tiền tố: có vẻ ổn
Nhưng đối với 3 trường còn lại tạo nên byte thì có vẻ như các bit bị đảo ngược
lflag:1; lá cờ:1;
Vì vậy nó phải là - 10100000=A0
Nhưng thực ra họ =>81=10000001
Điều này khiến tôi có rất nhiều câu hỏi...
Có mối quan hệ nào giữa endian nhỏ/endian lớn không?
Nếu vậy, đối tác của các hàm 8 bit như htonl và htons là gì.
Nếu không, vấn đề có thể là gì, hoặc tôi hoàn toàn hiểu sai điều gì đó?
Cách tiếp cận tốt nhất là gì? Sửa đổi thứ tự của các trường này trong cấu trúc
chính nó hoặc áp dụng một số toán tử bitwise và dịch chuyển các bit ở đây?
Đầu vào được cung cấp bởi dòng lệnh -
32+1+0+32
32 cuối cùng này không được sử dụng ở đây vì tôi đã sửa 32 trong chính mô-đun để thử nghiệm. Mặc dù vì mục đích thực tế của tôi, tôi cũng cần xem xét lĩnh vực này.
Xin hãy giúp tôi tìm bất kỳ giải pháp thay thế nào càng sớm càng tốt.
Cảm ơn trước.
biên tập:
Đây là cấu trúc thực tế mà tôi cần tạo và trong khi tạo nó, tôi cần cung cấp cho người dùng điều khoản để gán giá trị cho tất cả các trường thông qua GUI. (Hiện chỉ thông qua dòng lệnh linux).
Tôi nghĩ bây giờ tôi đã làm cho câu hỏi rõ ràng hơn, nhưng nếu cần thêm thông tin nào, tôi sẽ vui lòng thêm nó.
Cách trình biên dịch chọn đóng gói bitfield hoàn toàn phụ thuộc vào việc triển khai. Nó không nhất thiết phải liên quan gì đến độ bền.
htnol
(và tương tự) không hoạt động với bitfield. Nếu bạn cần một đơn hàng được đảm bảo, bạn sẽ phải tự đóng gói một đơn hàng theo cách thủ công uint8_t
. Ví dụ:
cấu trúc icmp_prefixopt {
u_int8_t icmpopt_type;
u_int8_t icpopt_len;
tiền tố u_int8_t;
nội dung u_int8_t;
}
...
popt->stuff = (lfag << 7) | (aflag << 6);
Tất nhiên, trong thực tế bạn nên sử dụng một cách hợp lý #định nghĩa
Thay vì Số ma thuật (cho 6 và 7). Bạn có thể quyết định gói nó trong một loạt các hàm setter và getter.
Tôi là một lập trình viên xuất sắc, rất giỏi!