Win32のランタイムダイナミックリンクメカニズムの次のラッパーを検討してください。
#include <boost/noncopyable.hpp>
#include <windows.h>
#include "Exception.hpp"
namespace WindowsApi
{
class RuntimeDynamicLinker : boost::noncopyable
{
HMODULE hMod_;
public:
RuntimeDynamicLinker(const wchar_t * moduleName)
{
hMod_ = LoadLibraryW(moduleName);
if (hMod_ == 0)
{
Exception::Throw(GetLastError());
}
}
template <typename T>
T GetFunction(const char* functionName)
{
FARPROC result = GetProcAddress(hMod_, functionName);
if (result == 0)
{
Exception::Throw(GetLastError());
}
return reinterpret_cast<T>(result);
}
~RuntimeDynamicLinker()
{
FreeLibrary(hMod_);
}
};
}
そしてサンプルクライアント:
typedef NTSTATUS (NTAPI * NtQueryInformationProcess_t)(
IN HANDLE,
IN PROCESS_INFORMATION_CLASS,
OUT PVOID,
IN ULONG,
OUT PULONG);
RuntimeDynamicLinker ntdll(L"ntdll.dll");
NtQueryInformationProcess_t NtQueryInformationProcess =
ntdll.GetFunction<NtQueryInformationProcess_t>("NtQueryInformationProcess");
基本的に、関数ポインタ型以外のGetFunction
場所で誰かが使用しようとした場合にエラーメッセージを追加したいと思います(ここで使用することを余儀なくされると、ユーザーエラーが隠される可能性があるため)。T
reinterpret_cast
ブーストタイプの特性を掘り下げてみると、既存のis_function
テンプレートがあることがわかりました。ただし、is_function
関数への参照を受け入れます。これは、私の場合はユーザーエラーになります(関数ポインターのみ)。
関数ポインタ型でないRuntimeDynamicLinker::GetFunction<T>()
場合、合理的に理解できるコンパイラエラーメッセージを生成するように変更するにはどうすればよいですか?T
(補足:私はいかなる種類のTMPも行ったことがないので、TMPの通常のユーザーにとって「基本的な」ことを恐れずに検討してください)