我正在将vxWorks应用程序转换为Linux。
以前,我有union
word
和struct
,因此当我访问struct
的成员时,我可以使用word's
} layout用于构建我的struct
成员。
但是,我不记得我是如何理解这一点的,它适用于vxWorks盒子。在我的vxWorks实例上,布局为:
typedef union Status
{
struct fields
{
uint32_t byteA : 1; // <31>
uint32_t blank : 23; // <30:8>
uint32_t bytesN : 8; // <7:0>
} fields;
uint32_t word;
}
从vxWorks移植到Linux时,我已经遇到了一些端点问题。因此,在linux上找出uint32_t
的布局非常重要。
答案 0 :(得分:3)
您可以通过指向包含值0x01的int
并将其转换为char *
来指示。如果第一个值等于零,那么系统是大端,否则它是小端。
以下是一个例子:
#include <inttypes.h>
#include <stdio.h>
int main(void)
{
uint32_t val = 0x01;
char * buff = (char *)&val;
if (buff[0] == 0)
{
printf("Big endian\n");
} else {
printf("Little endian\n");
};
return(0);
}
我在Linux,Solaris,OS X和FreeBSD上使用过这种方法。
答案 1 :(得分:1)
从您的评论到其他answer,您希望填充到word
union
成员中的任何内容都显示在fields.bytesN
成员中。要实现这一点,您必须具有某种预构建过程,该过程在检测到机器字节序后适当地布置field
位字段,或者创建2个结构,一个用于大端,另一个用于小端。
typedef union Status
{
struct fieldsBE
{
uint32_t byteA : 1; // <31>
uint32_t blank : 23; // <30:8>
uint32_t bytesN : 8; // <7:0>
} fieldsBE;
struct fieldsLE
{
uint32_t bytesN : 8; // <7:0>
uint32_t blank : 23; // <30:8>
uint32_t byteA : 1; // <31>
} fieldsLE;
uint32_t word;
};
int main()
{
bool isBigEndian = DetectEndianness(); // returns true if big endian
Status status;
status.word = 40;
if( isBigEndian ) {
uint8_t bytesN = status.fieldsBE.bytesN;
} else {
uint8_t bytesN = status.fieldsLE.bytesN;
}
}
当然,如果您只想支持端口中的小端,请使用fieldsLE
的布局,而不是您显示的原始布局。