【问题标题】:How do I interpret an #if/#else bitfield? (VC++ noob)如何解释#if/#else 位域? (VC++ 菜鸟)
【发布时间】:2019-02-14 08:17:02
【问题描述】:

背景: 我有一个错误的程序可以反编译一组特定的文件。这些错误与它正在反编译的记录无关,只是一些辅助的东西。我正在将程序移植到 AHK 以清理错误并添加一些功能。

问题: 它反编译的每个特定文件都引用该文件中每个记录的映射结构。其中大部分很容易确定。我在其中一个中遇到了位域表达式,我对如何阅读它有点困惑:

#if 1
    unsigned char vCombinedBits1;
    unsigned char vCombinedBits2;
#else
    unsigned char iPadding1_1 : 3;
    unsigned char vdirect : 1;

    unsigned char vitemspecific : 1;
    unsigned char vdamagerelated : 1;
    unsigned char vSigned : 1;
    unsigned char vSendmyspOther : 1;

    unsigned char iPading1 : 1;
    unsigned char iPading1_1 : 1;
    unsigned char vCSvSigned : 1;
    unsigned char vSaved : 1;

    unsigned char vfCallback : 1;
    unsigned char vfMin : 1;
    unsigned char vUpdateAnimRate : 1;
    unsigned char iPadding1_2 : 1;
#endif

我对 If/Else 逻辑并不陌生,但我 am 对 Visual C++ 并不陌生。

我假设的最终结果,基于thisthat:本质上,我将只读取两个字节而不考虑 vCombinedBits1 值并将每个位映射到我需要的变量。

假设 0x01 0x14 (0000 0001 0001 0100) 的样本将像这样映射,我是否正确: iPadding1_1 = 0 iPadding1_1 = 0 iPadding1_1 = 0 vdirect = 0

vitemspecific = 0 vdamagerelated =0 vSigned =0 vSendmyspOther = 1

iPading1 = 0 iPading1_1 = 0 vCSvSigned = 0 vSaved = 1

vfCallback = 0 vfMin = 1 vUpdateAnimRate =0 iPadding1_2 =0 ?

找到整个结构 here,#if 从第 649 行开始

【问题讨论】:

  • #else#endif 之间的代码由于预处理器而被完全忽略
  • 所以无论如何,我都会读取两个字节并相应地映射?我的示例地图正确吗?

标签: c++ visual-c++ structure porting bit-fields


【解决方案1】:

#if 1 的意思是“包括后面的所有内容,直到#else”;它后面的两行是代码的一部分。由于#if 条件为真,#else 的意思是“忽略后面的所有内容,直到#end;其余行不是代码的一部分。就好像这段代码已经写好了

unsigned char vCombinedBits1;
unsigned char vCombinedBits2;

【讨论】:

  • 那么无论如何,我都会读取两个字节并相应地映射?我的示例地图正确吗?
  • 示例地图中使用的名称不存在。该代码只定义了两个名称:vCombinedBits1vCombinedBits2
【解决方案2】:

基本上,我将只读取两个字节而不考虑 vCombinedBits1 值并将每个位映射到我需要的变量。

好的。

我是否正确假设 0x01 0x14 (0000 0001 0001 0100) 的样本将像这样映射:...

不完全是。位字段中位的顺序取决于特定的编译器 (TL;DR),并且您假设大端顺序。但在 VC++ 编译器的情况下,它是 little-endian。要判断您的假设是否正确,我们需要查看解码为位的实际数据样本。如果您希望此代码可移植到任何(未知)编译器和体系结构,请不要使用位字段来解码外部数据。

阿门!

【讨论】:

  • 这些是由第三方程序(用于该程序)从制表符分隔的文本文件创建的二进制文件。对于任何给定字段的任何给定值,它总是以相同的方式编译。我正在移植的 VC++ 程序会读取这些 bin 并重新创建源文本文件。基于此,我认为上面变量的顺序直接对应于遇到的位,因为他们遇到了。
  • 所以如果你知道第3方程序输出的是big endian bit order,并且有源输出的样本,你就可以测试你的解码了。要么匹配,要么不匹配。 50-50%。
  • 是的,弄明白了。感谢您的洞察力!
猜你喜欢
  • 2015-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-23
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
相关资源
最近更新 更多