封装统一模板调用动态库(dll)

17 篇文章 0 订阅
13 篇文章 0 订阅
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;

}

抛砖引玉,其他调用约定类型可以自行添加。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值