创建一个允许轻松创建虚拟函数包装器函数的C++宏
Creating a C++ macro that allows for easy creation of virtual-function wrapper functions
我正在为一个旧游戏编写修改,并利用基本的逆向工程来实现我的目标。从本质上讲,我一直在自己的代码中重新创建简单版本的逆向工程游戏结构和界面,将我的解决方案构建为共享对象并将其加载到游戏中。
我目前保持代码简单的解决方案是只在逆向工程接口的"我的版本"中包含我需要的功能,为此,我只需编写如下内容:
class GameManager {
public:
Game* GetGame();
Game* NextGame();
Game* PreviousGame();
int GameCount();
...
};
然后将函数实现为简单的包装器,这些包装器在虚拟方法表中按索引调用原始函数。这样我只能包含我需要的东西,等等。
其中每个都基本上由SomeType* SomeFunction(int param){ typedef thiscall blabla; call_vfunc(1,this,param); }
我想编写一个宏来自动化此过程,例如#define VFUNC(index, returnType, name, parameters)
这样简单易用的东西。
我搞砸了它,并为此进行了几次失败的尝试。最近的一个看起来像这样:
#define VFUNC(index, returnType, name, ...) returnType name(__VA_ARGS__) { return call_vfunc(index, this, ##__VA_ARGS__); }
当函数不带任何参数时,这有效,但问题是一旦我引入参数(例如,编写VFUNC(12, int, someFunction, int someParam)
,当我只想传递参数的名称时,我最终会传递整个声明。我一直在想一种方法,我可以把(int a,int b,int c(变成(a,b,c(,这样我就可以把它们传递给call_vfunc但到目前为止我什么都没有。
TLDR:我想编写一个宏来自动化创建这些虚拟函数"包装函数"的过程。
谢谢。任何帮助或指导都非常感谢=( 如果我弄清楚了,我会让你了解最新情况。
这是你的宏。
用法:
VFUNC(1, int, foo)
VFUNC_P(1, int, foo, (int,x))
VFUNC_P(1, int, foo, (int,x), (float,y))
实现:
#define CAT(x, y) CAT_(x, y)
#define CAT_(x, y) x##y
#define VA_COUNT(...) VA_COUNT_(__VA_ARGS__, 5, 4, 3, 2, 1,)
#define VA_COUNT_(p5, p4, p3, p2, p1, x, ...) x
#define FOR_EACH(macro, ...) CAT(FOR_EACH_, VA_COUNT(__VA_ARGS__))(macro, __VA_ARGS__)
#define FOR_EACH_1(m, p1 ) m p1
#define FOR_EACH_2(m, p1, p2 ) m p1 , m p2
#define FOR_EACH_3(m, p1, p2, p3 ) m p1 , m p2 , m p3
#define FOR_EACH_4(m, p1, p2, p3, p4 ) m p1 , m p2 , m p3 , m p4
#define FOR_EACH_5(m, p1, p2, p3, p4, p5) m p1 , m p2 , m p3 , m p4 , m p5
#define VFUNC_param_decl(type_, name_) ::std::enable_if_t<1, type_> name_
#define VFUNC_param_use(type_, name_) name_
#define VFUNC(index_, return_type_, name_)
return_type_ name_()
{ return call_vfunc(index_, this); }
#define VFUNC_P(index_, return_type_, name_, ...)
return_type_ name_( FOR_EACH(VFUNC_param_decl, __VA_ARGS__) )
{ return call_vfunc(index_, this, FOR_EACH(VFUNC_param_use, __VA_ARGS__)); }
上面提供的简单实现有一些限制:
对于参数- 为 0 的函数,有一个单独的宏。
- 您需要准备
O(n)
样板宏,其中n
是要支持的最大函数参数量。上面的代码最多支持 5 个参数。
有一种方法可以解决这两个问题,但它需要更丑陋的宏。这似乎不值得。
您可以重写这些宏以使用 Boost.Preprocessor 库。(使用BOOST_PP_VARIADIC_TO_SEQ
+BOOST_PP_SEQ_FOR_EACH
或类似的东西。
它将允许您摆脱样板(因为它将由库提供(。
- 通过构造函数创建的所有对象都具有相同的向量
- 通过构造函数创建一些值并尝试添加到文档中使用 rapidjson 不起作用
- 为 NewObjectA() 函数创建 jvalues 的参数数组时出错 - JNI Invocation API
- 使用带有 ref 参数的成员函数创建线程时出现编译错误
- C++ :: 如何捕获由 void 函数创建的矩阵
- 通过零参数构造函数创建的 glm::mat4 应该包含哪些值?
- 用于基于成员字段或函数创建比较器的快捷方式
- std::使用类成员函数创建线程 - 最佳实践
- 为C++重载函数创建SWIG类型映射
- 使用成员函数创建std::函数不会编译
- 如何为返回特定类型的函数创建 SWIG 类型图
- 为具有多个参数的函数创建 SWIG 类型图的更简单方法?
- 通过另一个宏创建的函数创建所有列表的宏
- std::map<int, A> 运算符 [] 需要使用空构造函数创建 A
- 无法使用 CreateWindowEx 函数创建窗口
- c++ 从成员函数创建新线程并移动对象和整个对象
- 无法使用 c++ 中的类成员函数创建/写入文件
- 使用makeword函数创建错误e0109-表观呼叫的括号前表达式必须具有(指针到 - )函数类型
- 为 OpenMP 函数创建别名 ||部分禁用 openMP
- 稍后使用<Class>调用类构造函数创建 std::vector