如何检查整个结构(无需填充)
我有一个包含EEPROM的内存的结构:
#pragma pack(push,1)
struct EEPROM_Memory
{
char Device_ID[8];
uint8_t Version_No;
otherRandomVariables...
};
#pragma pack(pop)
然后,我创建一个实例,填充结构并使用它来计算CRC:
CRC32::calculate(reinterpret_cast<uint8_t*>(&(memory)), sizeof(EEPROM_Memory));
我一直疯狂地试图弄清楚CRC检查为何返回不同的值。
我最好的猜测是Pragma Pack
不起作用,因此仍然有一些填充。因此,该填充是挥发性的,从而导致不同的CRC值。
什么是一个不错的解决方案(即没有手动检查其CRC结构中的每个值)?
任何建议都非常感谢!
ps我已经看了 this 给出许多有关该怎么做的建议。当然,这是一个普遍的问题!
PPS我使用的是ESP32微控制器,不确定哪个编译器。我正在使用的CRC库是 crc32 by Christopher Baker 。
I have a structure which contains memory for an EEPROM:
#pragma pack(push,1)
struct EEPROM_Memory
{
char Device_ID[8];
uint8_t Version_No;
otherRandomVariables...
};
#pragma pack(pop)
I then create an instance, populate the struct and calculate it's CRC using:
CRC32::calculate(reinterpret_cast<uint8_t*>(&(memory)), sizeof(EEPROM_Memory));
I have been going crazy trying to figure out why the CRC check returns different values.
My best guess is pragma pack
is not working therefore there is still some padding. This padding is volatile thus resulting in different CRC values.
What would be a nice solution (i.e not manually checking each value in the struct for their CRC)?
Any suggestions much appreciated!
P.S. I have looked at this question but sadly it does not give many suggestions on what to do. Surely this is a common problem!
P.P.S I am using an ESP32 microcontroller, unsure which compiler. The CRC library I am using is CRC32 by Christopher Baker.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
可以肯定的是,
pack
正在尽可能地工作,并且您使用的是错误的。请注意,包装不是递归的。因此,如果您的任何其他辅助功能是一个结构,那么该结构可能包含填充。
您应该做的是
static_assert
结构的大小。然后,您知道它是否具有预期的尺寸或一些填充物。如果包含任何结构,请首先断言这些结构的大小。Pretty sure the
pack
is working as it should and you are using it wrong.Note that pack is not recursive. So if your any of your otherRandomVariables is a struct then that struct may contain padding.
What you should do is
static_assert
the size of the struct. Then you know if it has the expected size or some padding. If it contains any structs assert the size of those structs first.我怀疑
内存
是一个指针,您正在使用其地址,从而计算指针的校验和遵循字节而不是 指向。reinterpret_cast
完全不必要,计算您使用的
函数已模板。和所有铸造关键字一样,reinterpret_cast
cripples编译器类型检查并禁用了许多有用的警告和错误,因此您确实应该认为这是最后的度假胜地。尝试以下试验:
当且仅当您尝试过并且它没有编译时,因为
内存
实际上不是指针,则I have a suspicion that
memory
is a pointer, and you're taking its address, thereby calculating the checksum of the pointer and following bytes rather than the data it points to.The
reinterpret_cast
is wholly unnecessary, thecalculate
function you are using is templated. And like all the cast keywords,reinterpret_cast
cripples compiler type-checking and disables a whole lot of useful warnings and errors, so you really should consider it a last resort.Try this:
If and only if you have tried that and it fails to compile because
memory
is not actually a pointer, then解决了 - 我在做一些愚蠢的事情。
以前,我为
EEPROM内存
使用了嵌套结构,正如Goswin所说,使用PACK无法递归起作用。因此,这导致了不必要的填充。我以前删除了这一点,因为它很可疑,但是由于愚蠢的错误而没有解决问题,我把它放回了!
感谢您的所有回复 - 很高兴知道,通过字节浏览结构字节并没有皱眉,您只需要超越意识到填充即可。
Solved - I was doing something silly.
Previously I used nested structures for the
EEPROM Memory
, and as Goswin said, using pack does not work recursively. So this resulted in unwanted padding.I had previously removed this as it was suspicious but after not resolving my problem, due to a silly mistake, I put it back in!
Thank you for all your responses - It is good to know that going through Structs byte by byte is not frowned upon, you just need to be hyper aware of padding.