c中同一结构的多个名称

Multiple names for the same struct in c

是否可以在 C 中为同一个结构创建多个名称? 这个想法是,具有相同布局但名称不同的通信协议中的数据结构可以共享相同的定义。

示例:

struct flags_type1 {
        uint8_t flag1;
        uint8_t flag2;
};

struct flags_type2 {
            uint8_t flag1;
            uint8_t flag2;
};
/* The flag layout for type 2 is identical to type 1, so somehow
 * just reuse the struct for type 1, but with a new name.
 * (For readability in the implementation. */

/* *** HERE: Insert solution code here. Something with typedef? *** */

struct flags_type3 {
        uint8_t flag1;
        uint8_t flag2;
        uint8_t flag3;
};

struct msg_object {
        uint8_t type_id_code;
        union {
                struct flags_type1 type1;
                struct flags_type2 type2;
                struct flags_type3 type3;
         } flags;
         uint8_t payload[7];
};


/* Utilization: */
struct msg_object *msg;
switch (msg->type_id_code) {
case TYPE1:
        do_things_type1(msg->flags.type1);
        break;
case TYPE2:
        do_things_type2(msg->flags.type2);
        break;
case TYPE3:
        do_things_type3(msg->flags.type3);
        break;
}

动机: 我正在实现一个通信协议,它可以传输具有不同类型的消息对象(特别是 CANopen 中的 SDO)。每个对象都有一个 5 位的状态标志字段,并且一些对象具有相同的此字段布局。还有一个标识对象类型的 3 位字段。这两个字段,被装入一个字节。

因此,我们的想法是根据类型标识符使用正确的标志布局。为了使这种标志布局的选择直观,让所有类型名称都出现,而不是定义相同的布局两次似乎是明智的。

从技术上讲,我想这是一个继承问题。

//奥顿

我不确定你到底想达到什么目的。如果我没误会的话,我想用typedef就可以做到。喜欢:

struct flags_type {
        uint8_t flag1;
        uint8_t flag2;
};

typedef struct flags_type type1;
typedef struct flags_type type2;

不能有两个带有不同标签(struct/union/enum 关键字之后的标签)的标签类型(标签类型是结构、联合或枚举) 指向同一类型(您可以将 struct x 视为指向类型定义的编译时指针)。换句话说,struct x 永远不会成为 struct y 的别名。但是你可以有不同的 typedefs 指向相同的类型。

typedef struct flags_type1 {
        uint8_t flag1;
        uint8_t flag2;
} flags_type1; //flags_type1 is now both a tag and a global typename
typedef flags_type1 flags_type2; //flags_type2 == flags_type1

你可能希望 flags_type1flags_type2 有不同的类型,但是(为了函数),在这种情况下,在纯 C 中你可以这样做:

struct flags2 { struct flags1 embedded; }

有了这个,您就必须提及成员名称(嵌入的)才能访问成员。这在直接 C 中是不可避免的(如果你不想为成员集使用宏),但在 gcc/clang 和 -fms-extensions 上你可以这样做:

struct flags2 { struct flags1; }
//w/ -fms-extensions, reuseses the body and
//makes struct flags2 implicitly convertible to struct flags1

然后直接访问成员。

除此之外,还有宏。

您不需要 typedef,您可以嵌套结构定义:


struct msg_object {
        uint8_t type_id_code;
        union {
                struct t01 {
                        uint8_t flag1;
                        } type1;
                struct t02 {
                        uint8_t flag1;
                        uint8_t flag2;
                        } type2;
                struct t03 {
                        uint8_t flag1;
                        uint8_t flag2;
                        uint8_t flag3;
                        } type3;
                } flags;
         uint8_t payload[7];
        };

处理程序代码:


switch (msg->type_id_code) { // may need to mask here ...
case TYPE1:
        do_things_type1(msg->flags.type1); // <<-- passed BY VALUE
        break;
        ...

The called function could be:

void do_things_type1(struct t1 this) {
        printf("%x", this.flag1 & 0xff);
        ...
}