基本的に Windows API をフックし、パラメーターと結果を記録するアプリケーション プロファイリング ライブラリを作成しています。私は、C++ テンプレートを使用してこれらのフックを生成し、新しいフックを追加する労力を最小限に抑える方法を考え出そうとしています。基本的に、私の各フックは次のようになります。
BOOL HookCloseHandle(HANDLE h)
{
BOOL result = RealCloseHandle(h);
if(g_profiling) record(result, h);
return result;
}
テンプレートを介してそれを一般化したいので、これらの関数は任意の Windows API 関数に対して生成できdecltype
ますdecltype(CreateFileW)
。これは可能ですか?私はfunction_traits
ブーストで見てきましたが、近いものを思いつくことができるようです:
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)>());
WhereHook
は、「実際の」関数をフックされたバージョンに置き換えるフック ライブラリによって提供されます。
CloseHandle
唯一のことは、現在関数内にあるそのテンプレート引数を削除する方法がわからないということですcall
。何か案は?