Mum*_*les 13 c gcc arm memory-management gcc4
我将应用程序移植到C中的ARM平台,该应用程序也在x86处理器上运行,并且必须向后兼容.
我现在有一些变量对齐的问题.我已经阅读了gcc手册,因为
__attribute__((aligned(4),packed))我解释了所说的内容,因为struct的开头与4字节边界对齐,并且由于packed语句,内部保持不变.
最初我有这个,但偶尔它与4字节边界不对齐.
typedef struct
{
unsigned int code;
unsigned int length;
unsigned int seq;
unsigned int request;
unsigned char nonce[16];
unsigned short crc;
} __attribute__((packed)) CHALLENGE;
Run Code Online (Sandbox Code Playgroud)
所以我把它改成了这个.
typedef struct
{
unsigned int code;
unsigned int length;
unsigned int seq;
unsigned int request;
unsigned char nonce[16];
unsigned short crc;
} __attribute__((aligned(4),packed)) CHALLENGE;
Run Code Online (Sandbox Code Playgroud)
该明白我前面所说似乎是不正确的,这两个结构是现在对齐到4字节边界,和现在的内部数据对齐到四个字节边界,但因为尾结构,该结构的大小已增加大小从42到44个字节.这个大小是至关重要的,因为我们有其他依赖于结构为42字节的应用程序.
有些人可以向我描述如何执行我需要的操作.任何帮助深表感谢.
cra*_*cot 12
如果你依赖于sizeof(yourstruct)42个字节,那么你将被一个不可移植的假设所困扰.你还没有说这是为了什么,但结构内容的字节顺序似乎很重要,所以你也可能与x86不匹配.
在这种情况下,我认为应对的唯一可靠方法是unsigned char[42]在重要的部分使用.首先编写一个精确的规范,准确说明这个42字节块中的哪些字段,以及哪个字节序,然后使用该定义编写一些代码,以便在它与可以与之交互的结构之间进行转换.代码可能是一次性序列化代码(也称为编组),或者是一堆getter和setter.
小智 5
这是为什么读取整个结构而不是成员失败的一个原因,应该避免.
在这种情况下,打包加上4对齐意味着将有两个字节的填充.发生这种情况是因为大小必须兼容才能将类型存储在一个数组中,所有项仍然对齐为4.
我想你有类似的东西:
read(fd, &obj, sizeof obj)
Run Code Online (Sandbox Code Playgroud)
因为您不想读取属于不同数据的那2个填充字节,所以必须明确指定大小:
read(fd, &obj, 42)
Run Code Online (Sandbox Code Playgroud)
您可以保持可维护性:
typedef struct {
//...
enum { read_size = 42 };
} __attribute__((aligned(4),packed)) CHALLENGE;
// ...
read(fd, &obj, obj.read_size)
Run Code Online (Sandbox Code Playgroud)
或者,如果您不能在C中使用C++的某些功能:
typedef struct {
//...
} __attribute__((aligned(4),packed)) CHALLENGE;
enum { CHALLENGE_read_size = 42 };
// ...
read(fd, &obj, CHALLENGE_read_size)
Run Code Online (Sandbox Code Playgroud)
在下一次重构时,我强烈建议您单独开始阅读每个成员,这可以很容易地封装在一个函数中.