C++ 宏在自定义偏移量处设置类字段

Posted

技术标签:

【中文标题】C++ 宏在自定义偏移量处设置类字段【英文标题】:C++ Macro to set class fields at custom offsets 【发布时间】:2021-06-23 15:18:55 【问题描述】:

我正在开发一个附加到程序并从目标程序中读取一些数据的 dll。我通过查找结构地址并将该地址转换为我的代码中相应结构的指针来做到这一点。

例子:

class Structure 
   char pad_1[0x30];
   float val1;
   float val2
   char pad_2[0x20];
   Structure* next;

如果我发现结构的地址是 0x1234,我可以做 (Structure*)0x1234 并且我可以访问它,请注意有一些填充值,这些值我根本不知道它们是什么或者我不需要它们。

我想在我的代码中编写这个结构(出于可维护性目的),如下所示:

class Structure 
   Offset(0x30)
   float val1;
   float val2;

   Offset(0x58) /// 0x30 + 2x floats + 0x20 padding
   Structure* next;

这个 Offset 宏应该自动添加填充,基本上用 Offset(num) 指定类中字段的偏移量,这个宏应该自动添加这个填充。

我不知道这是否可以使用 C 宏,现在我在 YAML 中定义我的模型并使用 python 脚本来生成它们,但是这有一些缺点......

【问题讨论】:

请注意,编译器可以自己添加填充。您需要通知编译器您需要打包结构(一些编译器特定的宏),并且只需插入虚拟字符数组作为自定义填充。在标准 C 或 C++ 中这是不可能的。 不,C 和 C++ 都不是这样工作的。 Marek R,我的问题是如何使用宏或类似知道字段的偏移量轻松插入这些填充 抛开这是否是一个好主意,你的第一个例子有什么问题?毕竟,您正在修补的structs 不太可能发生太大变化, 您可以添加静态断言来检查各个字段的偏移量,以确保没有损坏。 【参考方案1】:

在我看来,您想要做的基本上是使宏扩展为给定大小的 char 数组。这里唯一棘手的是结构成员的名称必须唯一,您可以使用__LINE__ 和宏中的双步连接来实现:

#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define OFFSET(size) char TOKENPASTE2(pad_, __LINE__)[size]

并以您想要的方式使用它。请注意,您会得到一些神秘的结构成员名称,这些名称在代码中不可见,但在开发过程中可能在 IDE 中可见。我不确定它是否真的更易于维护,我会手动将字符数组放在那里。

原答案来自:Creating C macro with ## and __LINE__ (token concatenation with positioning macro)

【讨论】:

在我的例子中 Offset(0x58) 应该产生 char pad[0x20] 但它总是会产生 pad[0x58] @orenrevenge 对,我没有注意到这部分。据我所知,当时没有办法做到这一点【参考方案2】:
Offset(0x58) /// 0x30 + 2x floats + 0x20 padding

这是不可能的——你不能喜欢“查询”在定义类型时“使用了”多少内存。该信息在类型被定义后是已知的。这在 C 语言中是不可能的。

【讨论】:

【参考方案3】:

这不是你用宏或结构解决的问题。

高层,你想要一个tuple<padding<30>, float, float, padding<58>, void*>。这不是std::tuple,但想法是相似的——你需要一个类模板,使用你自己的规则计算各种偏移量。

【讨论】:

以上是关于C++ 宏在自定义偏移量处设置类字段的主要内容,如果未能解决你的问题,请参考以下文章

ID 字段在自定义点类中间歇性丢失

如何在自定义类中调用“SetDlgItemText”?

如何在自定义 woocommerce 结帐字段中显示 $_SESSION 变量?

织梦CMS如何在自定义表单页调用arclist标签啊,怎么在自定义表单页调用无效!

在自定义分类模板中获取自定义字段

无法在自定义分类存档页面上获取选项页面自定义字段