[分享]变参模板封装调用约定
我们在搞事情的时候一般会这样写
1、定义函数指针,类型强转后调用
typedef void(__stdcall *FunctionDefine)(void* param); FunctionDefine function = (FunctionDefine)0xAABBCCDD; function(param);
2、内嵌汇编,并包一层函数
void function(void* param)
{
__asm{
push param
mov eax,0xAABBCCDD
call eax
}
}
其实可以试试这样写
template<typename R, typename... Args>
R std_call(void* address, Args...args)
{
typedef R(__stdcall *FunctionDefine)(Args...);
FunctionDefine function = (FunctionDefine)address;
return function(args...);
}
template<typename R, typename... Args>
R cdecl_call(void* address, Args...args)
{
typedef R(__cdecl *FunctionDefine)(Args...);
FunctionDefine function = (FunctionDefine)address;
return function(args...);
}
template<typename R, typename... Args>
R this_call(void* address, void* this_, Args...args)
{
typedef R(__thiscall *FunctionDefine)(void* this_, Args...);
FunctionDefine function = (FunctionDefine)address;
return function(this_, args...);
}
int result = std_call<int>(0xAABBCCDD, 1, 2, 3, 4);
result = cdecl_call<int>(0xAABBCCDD, 2, 3, 4, 5);
result = this_call<int>(0xAABBCCDD,(void*)0xDDEEDDEE, 2, 3, 4, 5);
这样我们就可以统一的管理、调用call啦,比如异常捕捉、日志、统计、行为序列
遇到的坑
typedef R(__cdecl *FunctionDefine1)(...); typedef R(__stdcall *FunctionDefine2)(...); 这里相当于定义了两个变参的函数指针,但实际上stdcall不支持变参,所以最后还是会变成cdecl的调用约定 typedef R(__cdecl *FunctionDefine1)(Args...); typedef R(__stdcall *FunctionDefine2)(Args...); 这样写才可以
