使用LoadLibrary动态加载DLL并使用其中的类

时间:2021-03-09 08:44:07

动态加载DLL并使用其中的函数,是大家经常用到的,那么直接使用LoadLibrary加载DLL来使用其中的类对象又该怎么做呢?本文给出方案&示例:

DLL - 头文件和导出方法

class IDLLIFsWrap
{
public:
    virtual void DeleteSelf(void) = 0;
    virtual int Add(int x, int y) = 0;
};

extern "C" __declspec(dllexport) long CreateIFsWrapObj(IDLLIFsWrap** ppObj);

DLL - 目标类的定义和实现

class CMyDLLIFsWrap : public IDLLIFsWrap
{
public:
    CMyDLLIFsWrap();
    virtual ~CMyDLLIFsWrap();
    virtual void DeleteSelf(void);
    virtual int Add(int x, int y);
};

long CreateIFsWrapObj(IDLLIFsWrap** ppObj)
{
    *ppObj = new CMyDLLIFsWrap();
    return 0;
}

CMyDLLIFsWrap::CMyDLLIFsWrap()
{
}
CMyDLLIFsWrap::~CMyDLLIFsWrap()
{
}

void CMyDLLIFsWrap::DeleteSelf(void)
{
    delete this;
}

int CMyDLLIFsWrap::Add(int x, int y)
{
    return x + y;
}

Demo - 使用DLL

class CMyDemoDlg : public CDialogEx
{
... ...
public:
    afx_msg void OnBnClickedOk();
    afx_msg void OnClose();

private:
    BOOL InitializeMyDLL();
    void UnInitializeMyDLL();

private:
    HINSTANCE           m_myDllHInst;
    IDLLIFsWrap*        m_pIFsWrapObj;
}

BOOL CMyDemoDlg::OnInitDialog()
{
... ...
InitializeMyDLL();
return TRUE;
}

void CMyDemoDlg::OnClose()
{
    UnInitializeMyDLL();

    CDialogEx::OnClose();
}
void CMyDemoDlg::OnBnClickedOk()
{
    if (nullptr != m_pIFsWrapObj)
    {
        int nRet = m_pIFsWrapObj->Add(3, 4);
        TRACE(_T("%d\n"), nRet);
    }
}

BOOL CMyDemoDlg::InitializeMyDLL()
{
    typedef long (*FunCreateIFsWrapObj)(IDLLIFsWrap **pp_obj);
    m_myDllHInst = LoadLibrary(_T("MyDLL.dll"));

    if (nullptr == m_myDllHInst)
        return FALSE;

    FunCreateIFsWrapObj funCreateObj = (FunCreateIFsWrapObj)GetProcAddress(m_myDllHInst, "CreateIFsWrapObj");
    if (nullptr == funCreateObj)
    {
        FreeLibrary(m_myDllHInst);
        m_myDllHInst = nullptr;
        return FALSE;
    }

    if (0 != funCreateObj(&m_pIFsWrapObj))
    {
        ASSERT(nullptr == m_pIFsWrapObj);
        FreeLibrary(m_myDllHInst);
        m_myDllHInst = nullptr;
        return FALSE;
    }

    ASSERT(nullptr != m_myDllHInst);
    ASSERT(nullptr != m_pIFsWrapObj);

    return TRUE;
}

void CMyDemoDlg::UnInitializeMyDLL()
{
    if (nullptr != m_pIFsWrapObj)
    {
        m_pIFsWrapObj->DeleteSelf();
        m_pIFsWrapObj = nullptr;
    }

    if (nullptr != m_myDllHInst)
    {
        FreeLibrary(m_myDllHInst);
        m_myDllHInst = nullptr;
    }
}