我在一个正在研究的项目中有一个联盟代表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;
我不想要。
有没有办法干净利落地做到这一点?
答案 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轻松发送任何数据类型。