数组采用结合的结构大小

时间:2018-01-18 09:29:25

标签: c arrays struct

我在一个正在研究的项目中有一个联盟代表USB操纵杆报告:

union {
    struct{
        uint8_t xaxis;
        uint8_t yaxis;
        uint8_t xraxis;
        uint8_t yraxis;
        uint8_t zraxis;
        uint8_t slider;

        uint8_t buttons8;
        uint8_t buttons16;
    };
    uchar buffer[8];
} report;

这样我就可以轻松地将值放入struct成员并使用缓冲区成员通过USB发送该数据,但是我最终修改了这个联合用于不同的项目(轴上的不同分辨率,更多/更少的按钮等)所以我必须弄清楚结构的新大小是什么来声明具有相同大小的数组。

有没有办法自动使数组大小相同?我想使用sizeof,这需要我改变这样的结构:

union {
    struct _data{ // either this
        uint8_t xaxis;
        uint8_t yaxis;
        uint8_t xraxis;
        uint8_t yraxis;
        uint8_t zraxis;
        uint8_t slider;

        uint8_t buttons8;
        uint8_t buttons16;
    } data; // or this
    uchar buffer[8];
} report;

然后我再也不能将数据放入结构中了:

report.xaxis = value;

但是:

report.data.xaxis = value;

我不想要。

有没有办法干净利落地做到这一点?

3 个答案:

答案 0 :(得分:1)

第1步是获得标准的C编译器。然后你可以使用匿名结构。要获得数组的适当大小,请使用struct标记,该标记仅在union内部需要。

typedef union {
    struct data {
        uint8_t xaxis;
        uint8_t yaxis;
        uint8_t xraxis;
        uint8_t yraxis;
        uint8_t zraxis;
        uint8_t slider;
        uint8_t buttons8;
        uint8_t buttons16;
    }; 
    uint8_t buffer[sizeof(struct data)];
} report_t;

...

  report_t r; 
  r.xaxis = 123;

答案 1 :(得分:1)

您可以将offsetof()用于结构

中的最后一个元素
union
{
    struct data
    {
        uint8_t xaxis;
        uint8_t yaxis;
        uint8_t xraxis;
        uint8_t yraxis;
        uint8_t zraxis;
        uint8_t slider;

        uint8_t buttons8;
        uint8_t buttons16;
    };
    uint8_t buffer[offsetof(struct data, buttons16)+1];
} report;

答案 2 :(得分:0)

其他人提出的解决方案将起作用。但是,它们都是hacks,因为你使用了union来轻松转换为字节。有一个更清洁的解决方案,即取消联盟。只需将struct设置为顶级类型,并使用通过USB发送数据的功能获取(void * data, size_t length)的参数。然后,您可以通过USB轻松发送任何数据类型。