使用C ++在联合中将结构作为嵌套的匿名结构导入

时间:2018-12-05 07:42:51

标签: c++ visual-c++ nested unions anonymous-struct

请考虑以下“不可更改”声明:

typedef struct T_MESSAGE
{
    unsigned int  uiTimestamp;
    unsigned char ucDataType;
    unsigned int  uiDataSize;
    unsigned char aucData[1024];
} TT_MESSAGE;

typedef struct T_SENSORDATA_HEADER
{
    unsigned char ucSensorType;
    unsigned char ucMountingPoint;
} TT_SENSORDATA_HEADER;

如果消息包含Sensor Data,则数据始终存储在aucData数组中,始终以Sensor Data Header开头。我想创建一个联合或结构,使我可以直接访问此类消息的所有成员,而不必使用其他变量名。 希望您通过查看我以前的尝试来了解我想要做什么。 我这样尝试过:

union SensorDataMessage
{
    struct T_Message;

    struct
    {
        unsigned : 32;  // Skip uiTimestamp
        unsigned : 8;   // Skip ucDataType
        unsigned : 32;  // Skip uiDataSize

        struct T_SENSORDATA_HEADER;
    };
};

这:

struct SensorDataOverlay
{
    unsigned : 32;  // Skip uiTimestamp
    unsigned : 8;   // Skip ucDataType
    unsigned : 32;  // Skip uiDataSize

    struct T_SENSORDATA_HEADER;
};

union SensorDataMessage
{
    struct T_Message;
    struct SensorDataOverlay;
};

但是这些都不起作用。最后,我希望能够编写如下内容:

int Evaluate(SensorDataMessage msg)
{
    unsigned char tmp = msg.ucDataType;
    unsigned char tmp2 = msg.ucSensorType;
    [...]
}

here中,我了解到我想做的事应该可行,但仅限于Visual C:

  

Microsoft C扩展允许您声明结构变量   在另一个结构中而不给它起名字。这些嵌套   结构称为匿名结构。 C ++不允许   匿名结构。

     

您可以访问匿名结构的成员,就像他们是   包含结构中的成员。

但是,这似乎并不完全正确,因为匿名结构也可以在Visual C ++中使用,就像建议here一样。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

以下是我发现的可以帮助您的地方:

  1. 必须将C / C ++编译器更改为编译为C代码(/ TC),以获得匿名结构支持。

enter image description here

  1. Evaluate()

  2. 的声明中缺少关键字 union
  3. SensorDataOverlay 中的匿名本机数据类型声明似乎会使编译器感到困惑,因此我尝试将它们收集为一个单一结构,作为 CommonHeader ,并放入一个包在 SensorDataOverlay 中。

我发现 T_MESSAGE SensorDataOverlay 在前三个字段中共享相同的方案,我想最好将其替换为 CommonHeader >,从数据继承的角度更有意义。由于在问题开始时您已经指出 T_MESSAGE 是不可更改的,因此我不会在以下代码中进行任何修改。

这里发布的完整代码可以运行,我认为内存偏移方案可以满足您的需求。


*struct CommonHeader
{
    unsigned int  skipUiTimestamp;
    unsigned char skipUcDataType;
    unsigned int  skipUiDataSize;
};

struct SensorDataOverlay
{
    /* Use CommonHeader instead */
    //unsigned : 32;  // Skip uiTimestamp
    //unsigned : 8;   // Skip ucDataType
    //unsigned : 32;  // Skip uiDataSize

    struct CommonHeader;
    struct T_SENSORDATA_HEADER;
};

union SensorDataMessage
{   
    TT_MESSAGE;
    struct SensorDataOverlay;
};

int Evaluate(union SensorDataMessage msg)
{
    unsigned char tmp = msg.uiDataSize;
    unsigned char tmp2 = msg.ucSensorType;

    return 0;
}*