考虑以下围绕 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
基本上,如果有人尝试使用whereT
函数指针类型以外的任何内容,我想添加一条错误消息(因为reinterpret_cast
我被迫在此处使用可能会隐藏用户错误)。
挖掘提升类型特征,我确实发现有一个现有的is_function
模板。但是,is_function
接受对函数的引用,这在我的情况下是用户错误(仅限函数指针)。
如果不是函数指针类型,我如何修改RuntimeDynamicLinker::GetFunction<T>()
以产生合理理解的编译器错误消息?T
(旁注:我从来没有做过任何类型的 TMP,所以不要害怕复习那些对 TMP 的普通用户来说“基本”的东西)