enum CallLibType
{
eStdCall,
eCdecl,
eFastCall
};
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...);
}
}
else if (eFastCall == eType)
{
typedef ResultType(__fastcall *FuncType)(params...);
FuncType func = (FuncType)GetProcAddress(hd, strFuncName.c_str());
if (func != NULL)
{
ret = func(para...);
}
}
FreeLibrary(hd);
}
template<typename ...params>
void CallLibrary(CallLibType eType, std::string strDll, std::string strFuncName, params... para)
{
HMODULE hd = LoadLibraryA(strDll.c_str());
if (0 == hd) return;
if (eStdCall == eType)
{
typedef void(__stdcall *FuncType)(params...);
FuncType func = (FuncType)GetProcAddress(hd, strFuncName.c_str());
if (func != NULL)
{
func(para...);
}
}
else if (eCdecl == eType)
{
typedef void(__cdecl *FuncType)(params...);
FuncType func = (FuncType)GetProcAddress(hd, strFuncName.c_str());
if (func != NULL)
{
func(para...);
}
}
else if (eFastCall == eType)
{
typedef void(__fastcall *FuncType)(params...);
FuncType func = (FuncType)GetProcAddress(hd, strFuncName.c_str());
if (func != NULL)
{
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);
// 能正常调用
CallLibrary(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;
{
// 无返回值版本
STARTUPINFOA st = { 0 };
CallLibrary<>(eStdCall, "kernel32.dll", "GetStartupInfoA", &st);
// 能正常调用
CallLibrary(eStdCall, "kernel32.dll", "GetStartupInfoA", &st);
}
return 0;
}
抛砖引玉,其他调用约定类型可以自行添加。