Skip to content

Commit c09a625

Browse files
Wend4rboeing666
andcommitted
Add CVTHookAuto & CVTFHookAuto class
to automatically get templated arguments of virtual method to hook Co-authored-by: Boeing666 <linbergh.dd@gmail.com>
1 parent eb7ed31 commit c09a625

1 file changed

Lines changed: 46 additions & 6 deletions

File tree

include/dynlibutils/vthook.hpp

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -238,18 +238,16 @@ class CVTFHook : public CVTHook<R, Args...>
238238
{
239239
public:
240240
using CBase = CVTHook<R, Args...>;
241-
using Function_t = R (*)(Args...);
242-
using Callback_t = std::function<R (Args...)>; // Allowing lambdas or other callable objects that match R(Args...) to be used as the hook target.
241+
using Function_t = std::function<R (Args...)>; // Allowing lambdas or other callable objects that match R(Args...) to be used as the hook target.
243242

244243
void Clear() { CBase::Clear(); sm_callback = nullptr; }
245244

246245
// Hooks takes labda callback:
247246
// - pVTable: CVirtualTable instance pointing to the target class’s vtable.
248247
// - nIndex (optional): Zero‐based index into the vtable to replace.
249248
// - func: Lambda callback to store and invoke when the hooked virtual function is called.
250-
template<auto METHOD>
251-
void Hook(CVirtualTable pVTable, Callback_t func) noexcept { Hook(pVTable, GetVirtualIndex<METHOD>(), func); }
252-
void Hook(CVirtualTable pVTable, std::ptrdiff_t nIndex, Callback_t func) noexcept
249+
template<auto METHOD> void Hook(CVirtualTable pVTable, Function_t &&func) noexcept { Hook(pVTable, GetVirtualIndex<METHOD>(), std::move(func)); }
250+
void Hook(CVirtualTable pVTable, std::ptrdiff_t nIndex, Function_t &&func) noexcept
253251
{
254252
assert(!sm_callback);
255253

@@ -267,7 +265,7 @@ class CVTFHook : public CVTHook<R, Args...>
267265
}
268266

269267
protected:
270-
inline static Callback_t sm_callback;
268+
inline static Function_t sm_callback;
271269
}; // class CVTFHook<R, Args...>
272270

273271
// A template class represents generic manager for multiple virtual‐table hooks of the same signature.
@@ -486,6 +484,48 @@ class CVTFMHook : public CVTMHook<R, Args...>
486484
inline static std::map<CVirtualTable, std::vector<Function_t>> sm_vcallbacks;
487485
}; // class CVTFHookSet<R, T, Args...>
488486

487+
// ========================================================================================
488+
// CVTHookAutoBase: Automatic wrapper for member function pointers
489+
// ========================================================================================
490+
//
491+
// This template uses partial specialization to inherit from a user-defined template T
492+
// instantiated with the signature of a given member function pointer. The T template must
493+
// accept the return type, a pointer to the class, and all method argument types.
494+
//
495+
// This pattern enables generic generation of function hooks or proxies with minimal
496+
// boilerplate: types are deduced from the function pointer automatically.
497+
//
498+
template<template<typename, typename...> class T, auto METHOD>
499+
class CVTHookAutoBase;
500+
501+
// Partial specialization for member function pointers:
502+
// Inherits from T<R, C*, Args...> for the signature R (C::*)(Args...).
503+
template<template<typename, typename...> class T, typename R, typename C, typename ...Args, R (C::*METHOD)(Args...)>
504+
class CVTHookAutoBase<T, METHOD> : public T<R, C*, Args...>
505+
{
506+
public:
507+
using CBase = T<R, C*, Args...>;
508+
using CBase::CBase;
509+
510+
[[ always_inline ]] // Wend4r (Linux): don't allow typeinfo/rtti to be generated for templated C argument.
511+
void Hook(CVirtualTable pVTable, CBase::Function_t &&func) noexcept
512+
{
513+
CBase::Hook(pVTable, GetVirtualIndex<METHOD>(), std::move(func));
514+
}
515+
}; // CVTHookAutoBase<T, R, C, Args...>
516+
517+
// ========================================================================================
518+
// Alias templates for concise hook type declarations
519+
// ========================================================================================
520+
//
521+
// These aliases allow you to declare an automatic hook/wrapper type for any member
522+
// function by simply specifying its pointer:
523+
//
524+
// CVTHookAuto<&MyClass::SomeVirtualMethod> myHook;
525+
//
526+
template<auto METHOD> using CVTHookAuto = CVTHookAutoBase<CVTHook, METHOD>;
527+
template<auto METHOD> using CVTFHookAuto = CVTHookAutoBase<CVTFHook, METHOD>;
528+
489529
// A final alias of CVTHook class.
490530
template<typename R, typename ...Args>
491531
class VTHook final : public CVTHook<R, Args...>

0 commit comments

Comments
 (0)