• 本站由于前段时间遭受到大量临时和国外邮箱注册,所以对可注册的邮箱类型进行了限制!

  • 本站会放置Google广告用于维持域名以及网站服务器费用。

  • 如果觉得本站的内容有帮助,可以考虑打赏博主哦!

  • 欢迎大家交换友链,可在https://www.stubbornhuang.com/申请友情链接进行友链交换申请!

  • 感谢大家访问本站,希望本站的内容可以帮助到大家!

  • 问题反馈可发送邮件到stubbornhuang@qq.com

  • 在本站开通年度VIP,无限制下载本站资源和阅读本站文章

  • 计算机图形学与计算几何经典必备书单整理,下载链接可参考:https://www.stubbornhuang.com/1256/

  • 工资「喂饱肚子」,副业「养活灵魂」!

我的项目 – Windows/Linux动态库加载类

我的项目 发布于2020-04-29 阅读 6,126次 0次评论 0次点赞 本文共3787个字,阅读需要10分钟。

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

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

文章末尾
上一篇
FFmpeg - 音频处理基本概念以及音频重采样(采样率转换)
FFmpeg
下一篇
WordPress - 为文章增加评论才可查看相关隐藏内容的代码
WordPress
当前分类随机文章推荐

发表评论

您必须 [ 登录 ] 才能发表留言!

关注我们的公众号

微信公众号