c中相同结构的多个名称

时间:2018-05-31 12:27:16

标签: c inheritance struct typedef

是否可以在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位字段。这两个字段适合单个字节。

因此,想法是基于类型标识符利用正确的标志布局。为了使这种标志布局的选择变得直观,使所有类型名称存在似乎是明智的,而不是两次定义相同的布局。

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

//的Audun

3 个答案:

答案 0 :(得分:2)

我不确定你想要达到的目标。如果我没有误解这一点,我想可以用typedef完成。像:

struct flags_type {
        uint8_t flag1;
        uint8_t flag2;
};

typedef struct flags_type type1;
typedef struct flags_type type2;

答案 1 :(得分:1)

你不能有两个带有不同标签的标记类型(标记类型是结构,联合或枚举)(结构/ 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

然后直接访问成员。

除此之外,总有宏。

答案 2 :(得分:0)

您不需要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);
        ...
}