1 Windows/Linux的动态库加载
该类用于在Windows/Linux加载动态库,并使用动态库,具体功能如下:
- 加载动态库
- 卸载动态库
- 获取动态库中接口函数指针
- 得到错误信息
- 得到动态库加载状态
Github地址 : https://github.com/HW140701/DynamicModuleLoader
2 代码
2.1 DynamicModuleLoader.h
头文件代码如下:
//!
//! @brief - Load dynamic libraries on Windows and Linux platforms
//!
//! @author - HuangWang
//!
//! @data - 2019-09-26
//!
#ifndef _DYNAMIC_MODULE_LOADER_H_
#define _DYNAMIC_MODULE_LOADER_H_
#include <string>
#include <fstream>
#define _DYNAMIC_LOAD
#define WINDOWS
#if defined(_DYNAMIC_LOAD)
#if defined(WINDOWS)
#include <Windows.h>
#define MODULE_HANDLER HINSTANCE
#elif defined(LINUX)
#include <dlfcn.h>
#define MODULE_HANDLER void*
#endif
#endif
#ifdef WINDOWS
#define PLATFORM_PATH_SPLIT_CHAR "\\"
#define PLATFORM_DYNAMIC_LIBRARY_PRE ""
#define PLATFORM_DYNAMIC_LIBRARY_EXT ".dll"
#elif defined (LINUX)
#define PLATFORM_PATH_SPLIT_CHAR "/"
#define PLATFORM_DYNAMIC_LIBRARY_PRE "lib"
#define PLATFORM_DYNAMIC_LIBRARY_EXT ".so"
#endif // WINDOWS
namespace DynamicModuleLoaderSpace
{
enum DynamicModuleState
{
DMS_UnLoaded = 0,
DMS_Loaded = 1
};
class DynamicModuleLoader
{
public:
DynamicModuleLoader();
virtual ~DynamicModuleLoader();
static bool IsFileExist(const std::string filePath);
bool LoadDynamicModule(const std::string dynamicModulePath);
void* GetFunction(const std::string functionName);
bool UnloadDynamicModule();
std::string GetErrorMessage();
bool GetDynamicModuleState();
private:
void GetInternalErrorMessge(int errorCode);
private:
MODULE_HANDLER m_DynamicModulePtr;
std::string m_ErrorMessage;
DynamicModuleState m_DynamicModuleState;
};
}
#endif /// _DYNAMIC_MODULE_LOADER_H_
cpp代码如下:
#include "DynamicModuleLoader.h"
namespace DynamicModuleLoaderSpace
{
DynamicModuleLoader::DynamicModuleLoader() :m_DynamicModulePtr(NULL), m_ErrorMessage(""), m_DynamicModuleState(DynamicModuleState::DMS_UnLoaded)
{
}
DynamicModuleLoader::~DynamicModuleLoader()
{
}
bool DynamicModuleLoader::IsFileExist(const std::string filePath)
{
std::fstream file;
file.open(filePath, std::ios::in);
if (file)
{
file.close();
return true;
}
else
{
return false;
}
}
bool DynamicModuleLoader::LoadDynamicModule(const std::string dynamicModulePath)
{
if (IsFileExist(dynamicModulePath))
{
#ifdef WINDOWS
m_DynamicModulePtr = LoadLibrary(dynamicModulePath.c_str());
#elif LINUX
m_DynamicModulePtr = dlopen(dynamicModulePath.c_str(), RTLD_NOW | RTLD_GLOBAL);
#endif // WINDOWS
if (m_DynamicModulePtr != NULL)
{
m_DynamicModuleState = DynamicModuleState::DMS_Loaded;
return true;
}
else
{
#ifdef WINDOWS
int errorCode = GetLastError();
#endif
GetInternalErrorMessge(errorCode);
return false;
}
}
return false;
}
void* DynamicModuleLoader::GetFunction(const std::string functionName)
{
if (m_DynamicModulePtr)
{
void* tempFunctionPtr = NULL;
#ifdef WINDOWS
tempFunctionPtr = GetProcAddress(m_DynamicModulePtr, functionName.c_str());
#elif LINUX
tempFunctionPtr = dlsym(m_DynamicModulePtr, functionName.c_str());
#endif // WINDOWS
if (tempFunctionPtr != NULL)
{
return tempFunctionPtr;
}
else
{
#ifdef WINDOWS
int errorCode = GetLastError();
#endif
GetInternalErrorMessge(errorCode);
}
}
return NULL;
}
bool DynamicModuleLoader::UnloadDynamicModule()
{
if (m_DynamicModulePtr)
{
#ifdef WINDOWS
if (FreeLibrary(m_DynamicModulePtr) == 0)
{
int errorCode = GetLastError(); // 得到错误代码
GetInternalErrorMessge(errorCode);
return false;
}
#elif LINUX
dlclose(m_DynamicModulePtr);
#endif
m_DynamicModuleState = DynamicModuleState::DMS_UnLoaded;
return true;
}
return false;
}
#ifdef WINDOWS
#endif
void DynamicModuleLoader::GetInternalErrorMessge(int errorCode)
{
std::string errorMessge = "";
#ifdef WINDOWS
LPVOID lpMsgBuf;
if (FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL,
errorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0,
NULL
))
{
errorMessge = (LPCTSTR)(lpMsgBuf);
LocalFree(lpMsgBuf);
}
#elif LINUX
errorMessge = dlerror();
#endif // WINDOWS
m_ErrorMessage = errorMessge;
}
std::string DynamicModuleLoader::GetErrorMessage()
{
return m_ErrorMessage;
}
bool DynamicModuleLoader::GetDynamicModuleState()
{
return (bool)m_DynamicModuleState;
}
}
本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:我的项目 – Windows/Linux动态库加载类
原文链接:https://www.stubbornhuang.com/807/
发布于:2020年04月29日 10:35:45
修改于:2023年06月26日 22:25:22
当前分类随机文章推荐
- 我的开源项目 - 支持C++11特性的定时器TinyTimer 阅读4669次,点赞0次
- 我的项目 - Windows/Linux动态库加载类 阅读3591次,点赞0次
- 我的开源项目 - 3DPoseEstimation从2D视频中估计人物三维姿势,并生成BVH文件 阅读13319次,点赞32次
- 我的开源项目 - 各种搜索引擎收录查询接口(Google/百度/必应/360/搜狗......) 阅读4676次,点赞3次
- 我的开源项目 - 使用OnnxRuntime在CPU端部署RTMPose玩转实时2D姿态估计 阅读889次,点赞1次
- 计算几何与计算机图形学必读书单整理 阅读23681次,点赞20次
- Mediapipe - 将Mediapipe handtracking封装成动态链接库dll/so,实现在桌面应用中嵌入手势识别功能 阅读11624次,点赞24次
全站随机文章推荐
- 资源分享 - Virtual Clothing - Theory and Practice 英文PDF下载 阅读1488次,点赞0次
- 姿态估计 - COCO-WholeBody数据集骨骼关节keypoint标注对应 阅读3837次,点赞0次
- 资源分享 - Digital Character Development - Theory and Practice , First Edition 英文高清PDF下载 阅读1728次,点赞0次
- TensorRT - workspace的作用 阅读1353次,点赞0次
- Visual Studio - 借助远程Linux服务器环境在Visual Studio中编写和远程调试Linux C++程序 阅读1541次,点赞0次
- 我的Windows装机必备软件备忘 阅读574次,点赞0次
- 工具软件 - 使用Potplayer录制在线直播视频流 阅读1099次,点赞0次
- 一文带你从欧拉角的角度搞懂左手坐标系到右手坐标系的转换 阅读17165次,点赞20次
- GCC - -fpic、-fPIC、-fpie、-fPIE编译选项的作用和区别 阅读266次,点赞0次
- 深度学习 - 语音识别框架wenet中的CTC Prefix Beam Search算法的实现 阅读557次,点赞0次
评论
169