C 如何从UCHAR数组中填充结构的位字段

C++ How can i fill the bit fields of a struct from a uchar array?

本文关键字:结构 填充 字段 数组 UCHAR      更新时间:2023-10-16

我有一个无符号的char数组,其值如下:

u_char *t_header[4]; //filled with values 0x00000047,0x00000004,0x00000093,0x00000012

我的结构如下:

            #pragma pack(push, 1)
            typedef struct th_struct {
                unsigned s_byte : 8;
                unsigned t_e_indicator : 1;
                unsigned p_u_s_indicator : 1;
                unsigned t_priority : 1;
                unsigned id : 13;
                unsigned t_s_control : 2;
                unsigned a_f_control : 2;
                unsigned c_counter : 4; 
            }th_struct;
            #pragma pack(pop)

我试图填充以下结构字段:

            const struct  th_struct *tsh;
            tsh = (struct th_struct*)(t_header);

它在十六进制中以tsh->s_byte = CC_1填充CC_1,但其余的字段都是0

我该怎么做才能正确填充struct th_struct *tshu_char *t_header[4]值,如下所示?

0100 0111 .... .... .... .... .... .... = (0x00000047) tsh->s_byte .... .... 0... .... .... .... .... .... = 0 tsh->t_e_indicator .... .... .0.. .... .... .... .... .... = 0 tsh->p_u_s_indicator .... .... ..0. .... .... .... .... .... = 0 tsh->t_priority .... .... ...0 0100 1001 0011 .... .... = (0x00000493) tsh->id .... .... .... .... .... .... 00.. .... = (0x00000000) tsh->t_s_control .... .... .... .... .... .... ..01 .... = (0x00000001) tsh->a_f_control .... .... .... .... .... .... .... 0010 = 2 tsh->c_counter

谢谢!

首先,您在这里遇到问题:

u_char *t_header[4];

是4个指针 - 不是4个U_CHAR。您可能想要:

u_char t_header[4];

下一个问题是位字段的布局取决于实现。

因此,(通常)编写假定特定布局的代码是一个坏主意。此类代码只能在编写代码时使用的特定系统上运行,即代码是不可存储的。

我建议您使用Shift oterator >>和位和操作员&准确选择所需的位:

unsigned char t_header[4] = {0x47, 0x04, 0x93, 0x12};
th_struct tsh;
tsh.s_byte = t_header[0];
tsh.t_e_indicator = (t_header[1] >> 7) & 0x1;
tsh.p_u_s_indicator = (t_header[1] >> 6) & 0x1;
tsh.t_priority = (t_header[1] >> 5) & 0x1;
tsh.id = ((unsigned)(t_header[1] & 0x1f) << 8) + t_header[2];
tsh.t_s_control = (t_header[3] >> 6) & 0x3;
tsh.a_f_control = (t_header[3] >> 4) & 0x3;
tsh.c_counter = t_header[3] & 0xf;
printf("s_byte=%xn", tsh.s_byte);
printf("t_e_indicator=%xn", tsh.t_e_indicator);
printf("p_u_s_indicator=%xn", tsh.p_u_s_indicator);
printf("t_priority=%xn", tsh.t_priority);
printf("id=%xn", tsh.id);
printf("t_s_control=%xn", tsh.t_s_control);
printf("a_f_control=%xn", tsh.a_f_control);
printf("c_counter=%xn", tsh.c_counter);

然后您还可以避免拥有包装的结构。

您可以做这样的事情:

struct  th_struct t_header = {
    .s_byte = 0x47,
    .t_e_indicator = 0,
    .p_u_s_indicator = 0,
    .t_priority = 0,
    .id = 0x00000493,
    .t_s_control = 0,
    .a_f_control = 1,
    .c_counter = 2 };

,然后: const struct th_struct* tsh = &t_header;

我认为这很容易。

您必须更改这样的方式的方式:

u_char t_header[4];
t_header[0] = 0x47;     // s_byte
t_header[1] = (u_char)
        (0x00           // t_e_indicator
         | (0x00 << 1)  // p_u_s_indicator
         | (0x00 << 2)  // t_priority
         | (0x493 << 3)); // id[0..4]
t_header[2] = (u_char) ((0x493 << 3) >> 8); // id [5..12]
t_header[3] = (u_char)
        (0x00           // t_s_control
        | (0x01 << 2)   // a_f_control
        | (0x02 << 4)); // c_counter
const struct th_struct* tsh = (th_struct*)t_header;

或更改结构顺序:

#pragma pack(push, 1)
           typedef struct th_struct2 {
               unsigned s_byte : 8;
               unsigned id1 : 5;
               unsigned t_e_indicator : 1;
               unsigned t_priority : 1;
               unsigned p_u_s_indicator : 1;
               unsigned id2 : 8;
               unsigned c_counter : 4;
               unsigned a_f_control : 2;
               unsigned t_s_control : 2;
           }th_struct2;
           #pragma pack(pop)

其中ID1是较高的OD ID,而ID2则是下部。