I'm using detours and I find that the cast that they use very ugly, so I've written a couple of template functions to do the casting for me.
// Cast a function pointer to a void *
template <typename RET_TYPE, typename...ARGs>
void* fnPtrToVoidPtr(RET_TYPE(WINAPI * pOriginalFunction)(ARGs...))
{
return (void*)pOriginalFunction;
}
// Cast a function pointer that is referencable to a void *&
template <typename RET_TYPE, typename...ARGs>
void*& fnPtrRefToVoidPtrRef(RET_TYPE(WINAPI*& pOriginalFunction)(ARGs...))
{
return (void*&)pOriginalFunction;
}
This allows me to do the following call:
BOOL (WINAPI *pDestroyIcon)(HICON) = DestroyIcon;
DetourAttach(&fnPtrRefToVoidPtrRef(pDestroyIcon), fnPtrToVoidPtr(DestroyIcon));
However, I was wondering if I could consolidate the two function names fnPtrRefToVoidPtrRef
and fnPtrToVoidPtr
into one name.
Doing the following doesn't work as it can't deduce the template arguments:
// Cast a function pointer to a void *
template <typename RET_TYPE, typename...ARGs>
void* fnPtrToVoidPtr(RET_TYPE(WINAPI * & pOriginalFunction)(ARGs...))
{
return (void*)pOriginalFunction;
}
// Cast a function pointer that is referencable to a void *&
template <typename RET_TYPE, typename...ARGs>
void*& fnPtrToVoidPtr(RET_TYPE(WINAPI * && pOriginalFunction)(ARGs...))
{
return (void*&)pOriginalFunction;
}
BOOL (WINAPI *pDestroyIcon)(HICON) = DestroyIcon;
void* p1 = fnPtrToVoidPtr(DestroyIcon);
void** p2 = &fnPtrToVoidPtr(pDestroyIcon);
causing the following error:
// error C2784: 'void *&fnPtrToVoidPtr(RET_TYPE (__stdcall *&&)(ARGs...))' : could not deduce template argument for 'overloaded function type' from 'overloaded function type'
Using my original functions, this works fine:
BOOL (WINAPI *pDestroyIcon)(HICON) = DestroyIcon;
void* p1 = fnPtrToVoidPtr(DestroyIcon);
void** p2 = &fnPtrRefToVoidPtrRef(pDestroyIcon);
However, if I change fnPtrRefToVoidPtrRef
to this:
// Cast a function pointer that is referencable to a void *&
template <typename RET_TYPE, typename...ARGs>
void*& fnPtrRefToVoidPtrRef(RET_TYPE(WINAPI*&& pOriginalFunction)(ARGs...))
{
return (void*&)pOriginalFunction;
}
I get the following error:
error C2664: 'void *&fnPtrRefToVoidPtrRef<BOOL,HICON>(RET_TYPE (__stdcall *&&)(HICON))' : cannot convert argument 1 from 'BOOL (__stdcall *)(HICON)' to 'BOOL (__stdcall *&&)(HICON)'
Which seems to be why it can't do template deduction, it doesn't recognize it to be the same (or convertible?) type. Is there a way to get C++ to properly deduce the function pointer?