gpt4 book ai didi

c++ - 读取由结构定义的二进制文件

转载 作者:太空狗 更新时间:2023-10-29 19:45:09 30 4
gpt4 key购买 nike

有人能指出我如何读取由 C 结构定义的二进制文件的正确方向吗?它在结构内部有一些#define,这让我觉得它会使事情复杂化。
结构看起来像这样:(尽管它比这更大更复杂)

struct Format {
unsigned long str_totalstrings;
unsigned long str_name;
#define STR_ORDERED 0x2
#define STR_ROT13 0x4
unsigned char stuff[4];
#define str_delimiter stuff[0]
}

如果有人能为我指明正确的方向,我将不胜感激。或者是否有任何涵盖该主题的教程?

非常感谢您的帮助。

最佳答案

有一些坏点子和好点子:

这是个坏主意:

  • 将原始缓冲区类型转换为结构
    • endianness解析整数 >1 字节长或 float 时的问题(小端与大端)
    • byte alignment issues在非常依赖编译器的结构中。可以尝试禁用对齐(或强制执行一些手动对齐),但这通常也是一个坏主意。至少,让 CPU 访问未对齐的整数会破坏性能。内部 RISC 核心必须执行 3-4 次操作而不是 1 次(即“在第一个字中执行第 1 部分”、“在第二个字中执行第 2 部分”、“合并结果”)才能每次访问它。或者更糟的是,控制对齐的编译器编译指示将被忽略,您的代码将中断。
    • 对于常规 intlongshort 等 C/C++ 类型,没有精确的大小保证。您可以使用 int16_t 之类的东西,但这些只能在现代编译器上使用。
    • 当然,当使用引用其他结构的结构时,这种方法会完全失效:必须手动展开它们。
  • 手动编写解析器:这比乍看起来要难得多。
    • 一个好的解析器需要在每个阶段做大量的健全性检查。很容易错过一些东西。如果不使用异常,就更容易错过一些东西。
    • 如果您的解析代码不是异常安全的(即以一种可以在某些点中断并且不会泄漏内存/忘记完成某些对象的方式编写),使用异常会使您容易失败
    • 可能存在性能问题(即执行大量无缓冲的 IO 而不是执行一个操作系统 read 系统调用然后解析缓冲区 — 反之亦然,一次读取整个内容而不是更细粒度,懒惰在适用的地方阅读)。

这是个好主意

  • 跨平台。几乎不言自明,近年来所有移动设备、路由器和物联网设备都在蓬勃发展。
  • 去声明。考虑使用任何声明性规范来描述您的结构,然后使用解析器生成器来生成解析器。

有几种工具可以做到这一点:

  • Kaitai Struct — 目前为止我最喜欢的,跨平台、跨语言 — 也就是说,您只需描述一次结构,然后就可以将其编译成 C++、C#、Java、Python、Ruby、PHP 等语言的解析器。
  • binpac — 相当过时,但仍然可用,仅限 C++ — 在意识形态上类似于 Kaitai,但自 2013 年以来不受支持
  • Spicy — 据说是 binpac 的“现代重写”,又名“binpac++”,但仍处于开发的早期阶段;可以用于较小的任务,也只能用于 C++。

关于c++ - 读取由结构定义的二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/868530/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com