enum CallLibType
{
eStdCall,
eCdecl
};
template<typename ResultType, typename ...params>
void CallLibrary(CallLibType eType, std::string strDll, std::string strFuncName, ResultType& ret, params... para)
{
HMODULE hd = LoadLibraryA(strDll.c_str());
if (0 == hd) return;
if (eStdCall == eType)
{
typedef ResultType(__stdcall *FuncType)(params...);
FuncType func = (FuncType)GetProcAddress(hd, strFuncName.c_str());
if (func != NULL)
{
ret = func(para...);
}
}
else if(eCdecl == eType)
{
typedef ResultType(__cdecl *FuncType)(params...);
FuncType func = (FuncType)GetProcAddress(hd, strFuncName.c_str());
if (func != NULL)
{
ret = func(para...);
}
}
FreeLibrary(hd);
}
測試代碼
int main()
{
BOOL bRet = FALSE;
OSVERSIONINFOA os = { 0 };
ZeroMemory(&os, sizeof(OSVERSIONINFOA));
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
CallLibrary<BOOL>(eStdCall, "kernel32.dll", "GetVersionExA", bRet, &os);
std::cout << "bRet = " << bRet << std::endl;
std::cout << "dwMajorVersion = " << os.dwMajorVersion << std::endl;
std::cout << "dwMinorVersion = " << os.dwMinorVersion << std::endl;
std::cout << "dwBuildNumber = " << os.dwBuildNumber << std::endl;
std::cout << "dwPlatformId = " << os.dwPlatformId << std::endl;
std::cout << "szCSDVersion = " << os.szCSDVersion << std::endl;
CHAR buff[512] = { 0 };
DWORD dRet = 0;
CallLibrary<DWORD>(eStdCall, "kernel32.dll", "GetModuleFileNameA", dRet, NULL, buff, 512);
std::cout << std::endl;
std::cout << "dRet = " << dRet << std::endl;
std::cout << "buff = " << buff << std::endl;
return 0;
}
測試結果
拋磚引玉,可以再定製一個無返回值的版本。其他調用約定類型可以自行添加。