如何检查整个结构(无需填充)

发布于 2025-02-10 08:38:20 字数 838 浏览 2 评论 0原文

我有一个包含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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

薄暮涼年 2025-02-17 08:38:20

可以肯定的是,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.

想挽留 2025-02-17 08:38:20

我怀疑内存是一个指针,您正在使用其地址,从而计算指针的校验和遵循字节而不是 指向

reinterpret_cast完全不必要,计算您使用的函数已模板。和所有铸造关键字一样,reinterpret_cast cripples编译器类型检查并禁用了许多有用的警告和错误,因此您确实应该认为这是最后的度假胜地。

尝试以下试验:

auto result = CRC32::calculate(memory, 1);

当且仅当您尝试过并且它没有编译时,因为内存实际上不是指针,则

auto result = CRC32::calculate(&memory, 1);

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, the calculate 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:

auto result = CRC32::calculate(memory, 1);

If and only if you have tried that and it fails to compile because memory is not actually a pointer, then

auto result = CRC32::calculate(&memory, 1);
醉城メ夜风 2025-02-17 08:38:20

解决了 - 我在做一些愚蠢的事情。

以前,我为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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文