C 更改并集内的尾数或字节顺序

C 更改并集内的尾数或字节顺序,c,unions,C,Unions,我正在从事一个涉及通信的项目。我希望能够获取一个结构并将其类型转换为字节,为传输做准备。不幸的是,endianness不适合我 我使用的标准具有以下定义: uint8_t address; uint8_t function; uint8_t startAddressHi; uint8_t startAddressLo; uint8_t numberOfRegistersHi; uint8_t numberOfRegistersLo; typedef union{ struct rtu

我正在从事一个涉及通信的项目。我希望能够获取一个结构并将其类型转换为字节,为传输做准备。不幸的是,endianness不适合我

我使用的标准具有以下定义:

uint8_t address;
uint8_t function;
uint8_t startAddressHi;
uint8_t startAddressLo;
uint8_t numberOfRegistersHi;
uint8_t numberOfRegistersLo;
typedef union{

    struct rturxfields{
        /* header */
        uint8_t address;
        uint8_t function;

        /* data */
        uint16_t startAddress;   // <= needs some special sauce
        uint16_t numberOfRegisters;
    }RtuRxFields;

    struct rturxfieldbytes{
        /* header */
        uint8_t address;
        uint8_t function;

        /* data */
        uint8_t startAddressHi;
        uint8_t startAddressLo;
        uint8_t numberOfRegistersHi;
        uint8_t numberOfRegistersLo;
    }RtuRxFieldBytes;

    uint8_t array[RX_FRAME_LENGTH];
}RtuRxFrame;
如果能够将cast输入到
uint8_t
并简单地一次性传输整个结构就好了,但问题是
startAddress
numberOfRegisters
Hi
字节的索引较低。我希望有一些鲜为人知的改变定义字节顺序的方法:

uint8_t address;
uint8_t function;
uint8_t startAddressHi;
uint8_t startAddressLo;
uint8_t numberOfRegistersHi;
uint8_t numberOfRegistersLo;
typedef union{

    struct rturxfields{
        /* header */
        uint8_t address;
        uint8_t function;

        /* data */
        uint16_t startAddress;   // <= needs some special sauce
        uint16_t numberOfRegisters;
    }RtuRxFields;

    struct rturxfieldbytes{
        /* header */
        uint8_t address;
        uint8_t function;

        /* data */
        uint8_t startAddressHi;
        uint8_t startAddressLo;
        uint8_t numberOfRegistersHi;
        uint8_t numberOfRegistersLo;
    }RtuRxFieldBytes;

    uint8_t array[RX_FRAME_LENGTH];
}RtuRxFrame;
typedef联合{
结构RTURX字段{
/*标题*/
uint8_t地址;
uint8_t功能;
/*资料*/

uint16\u t startAddress;//您可以做的一件事是使用
htons
ntohs
在主机字节顺序(机器相关)和网络字节顺序(big-endian)之间转换16位值。在写入16位值时,通过
htons
将其传递,以正确的顺序放入字节

myunion.RtuRxFields.numberOfRegisters = htons(5);
如果您无法访问这些函数,可以使用位移位获取高字节和低字节,并将它们分别写入相关字段:

uint16_t registers = 5;
...
myunion.RtuRxFieldBytes.numberOfRegistersHi = (registers >> 8) & 0xff;
myunion.RtuRxFieldBytes.numberOfRegistersLo = registers & 0xff;

由于结构填充,通过网络发送结构可能会有问题。两台不同机器上的两个不同编译器可能会使同一个结构的大小不同。有关详细信息,请参阅。

这是一个令人惊讶的难题。请参阅主题中的。我应该将此添加到我的帖子中。我为微控制器和它没有访问网络库的权限。我会将此信息添加到我的初始帖子中,并通读您的参考资料。谢谢!@slitlynbble查看我的编辑。您可以使用位操作提取相关字节以写入正确的位置。这是可以在编译时完成的吗?您的示例似乎发生在运行时时间。@除非您计划设置常量数据,否则它必须在运行时完成。按位操作非常便宜,所以我认为使用它们不会有什么问题。您是对的,没有什么问题。我只是希望有更优雅的东西,谢谢您的时间!