I'm writing a application profiling library that basically hooks Windows APIs and records the parameters and results. I'm trying to come up with a way to generate these hooks in a manner using C++ templates that requires minimal effort to add new hooks. Basically, each one of my hooks look like the following:
BOOL HookCloseHandle(HANDLE h)
{
BOOL result = RealCloseHandle(h);
if(g_profiling) record(result, h);
return result;
}
I want to generalize that via templates so these functions can be generated for any arbitrary Windows API function via decltype
, e.g. decltype(CreateFileW)
. Is this even possible? I've been looking at function_traits
in Boost and it seems I'm able to come up with something close:
decltype(&CloseHandle) RealCloseHandle = &::CloseHandle;
template <typename R, typename P1, R(*F)(P1)>
R perform_1(P1 value)
{
R result = F(value);
if (profiling) record(result, value);
return result;
}
template <typename T>
T* call(const T& original)
{
typedef boost::function_traits<T> traits;
switch (traits::arity)
{
case 1:
return &perform_1<traits::result_type, traits::arg1_type, RealCloseHandle>;
// ...
}
return nullptr;
};
// setup code
Hook(RealCloseHandle, call<decltype(CloseHandle)>());
Where Hook
is provided by the hooking library that replaces a "real" function with my hooked version.
The only thing is, i'm not sure how to remove that CloseHandle
template argument that's currently inside the call
function. Any ideas?