linux和windows下动态链接库调用类

LibSo.h

#pragma once

typedef void* HANDLE;
typedef void* ProcAddr;

#include <string>

namespace COMMON
{
	namespace UTILITY
	{
		class LibSo
		{
		public:
			LibSo();
			virtual ~LibSo();
			static HANDLE LoadLib(const std::string& path);
			static void FreeLib(HANDLE hHandle);
			static ProcAddr GetProcAddr(HANDLE hHandle, const std::string& proName);
		};
	}
}

LibSo.cpp

#include "LibSo.h"
#if defined(_WIN32) || defined(_WIN64)
#include <winsock2.h>
#include <windows.h>
#elif defined(__linux__)
#include <dlfcn.h>
#endif

namespace COMMON
{
	namespace UTILITY
	{
		LibSo::LibSo()
		{
		}
		
		LibSo::~LibSo()
		{
		}

		HANDLE LibSo::LoadLib(const std::string& path)
		{
#if defined(_WIN32) || defined(_WIN64)
			HMODULE h = NULL;
			char szPath[MAX_PATH] = {0};
			char * p = NULL;

			if (path.empty())
			{
				return nullptr;
			}

			//replace '/' by '\\' if exist '/'.
#if (_MSC_VER >= 1500 && !defined _WIN32_WCE)
			strcpy_s(szPath, MAX_PATH, path.c_str());
#else
			strcpy(szPath, path.c_str());
#endif

			p = szPath;
			while ((p = strchr(p, '/')) != NULL)
			{
				*p = '\\';
			}

#if defined _WIN32_WCE
			wchar_t wPath[260] = { 0 };
			MultiByteToWideChar(CP_ACP, 0, szPath, strlen(szPath), wPath, sizeof(wPath));
			h = LoadLibraryEx(wPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
#else
			h = LoadLibraryEx(szPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
#endif
			if (h == NULL)
			{
#if defined _WIN32_WCE
				h = LoadLibraryEx(wPath, NULL, 0);
#else
				DWORD ret = GetLastError();
				h = LoadLibraryEx(szPath, NULL, 0);
#endif
			}

			return h;
#elif defined(__linux__)

			if (path.empty())
			{
				return nullptr;
			}

			HANDLE dlsm = dlopen(path.c_str(), RTLD_LAZY);
			char* iErr = nullptr;
			if (dlsm == nullptr)
			{
				iErr = dlerror();
				printf("load failed: %s\n", iErr);
			}
			return dlsm;
#endif
		}

		void LibSo::FreeLib(HANDLE hHandle)
		{
#if defined(_WIN32) || defined(_WIN64)
			if ((hHandle != nullptr) && (FreeLibrary((HMODULE)hHandle)))
			{
				return;
			}
#elif defined(__linux__) || defined(__APPLE__)
			if ((hHandle) && (!dlclose(hHandle)))
			{
				return;
			}
#endif

		}

		ProcAddr LibSo::GetProcAddr(HANDLE hHandle, const std::string& proName)
		{
#if defined(_WIN32) || defined(_WIN64)
			if (hHandle == nullptr || proName.empty())
			{
				return nullptr;
			}

#if defined _WIN32_WCE
			return (ProcAddr)GetProcAddressA((HMODULE)hHandle, proName.c_str());
#else
			return (ProcAddr)GetProcAddress((HMODULE)hHandle, proName.c_str());
#endif
#elif defined(__linux__)
			if ( hHandle != nullptr && !proName.empty() )
			{
				return (ProcAddr)dlsym(hHandle, proName.c_str());
			}

			return NULL;
#endif
		}
	}
}

编译时要加上 -ldl 选项 ,以产生可调用动态链接库的执行代码。

main.cpp

#include "LibSo.h"
#include<iostream>

#if defined(WIN32) || defined(WIN64)
	#define CALLBACK __stdcall
#else
	#define CALLBACK 
#endif
typedef long  (CALLBACK* Protocol_Init)();

int main(void)
{	
	std::string path;
#if defined(WIN32) || defined(WIN64)
	path = "test.dll";
#else
	path = "test.so"; //假设test动态链接库里有Protocol_Init函数
#endif

	HANDLE hDllModule;
	hDllModule= COMMON::UTILITY::LibSo::LoadLib(path);
	Protocol_Init= reinterpret_cast<Protocol_Init>(COMMON::UTILITY::LibSo::GetProcAddr(hDllModule, "Protocol_Init"));
	if (nullptr == m_funcProtocol_Init)
	{
		printf("Protocol_Init function is Null!\n");
		result = false;
	}
	
	if(Protocol_Init)
	{
		Protocol_Init();//调用test动态库里面的Protocol_Init函数
	}
		
	COMMON::UTILITY::LibSo::FreeLib(hDllModule);//释放
	
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值