首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++基於DLL的應用程序插件架構設計與實現

     編輯:VC 教學

插件技術的優勢

插件機制讓軟件功能擴展不再侷限於廠商,第三方開發者遵循接口標準即可無縫整合,實現用戶個性化定制。同時便於模塊化升級維護,只需替換對應 DLL。

設計思路與接口標準

1. 插件存放與加載時機

應用程式啟動時掃描指定目錄(如 Plugins)下的所有 .dll,動態加載;退出時釋放。

2. 統一導出函數:Plug_CreateObject

BOOL Plug_CreateObject(void** pobj) {
    *pobj = new CPlugA;
    return *pobj != NULL;
}

主程式調用此函數獲取插件對象指針。

3. 基類 CPlugBase 定義核心契約

class CPlugBase {
public:
    virtual HICON GetIcon() = 0;           // 取得工具欄圖標
    virtual void Interface(int k) = 0;     // 功能入口
    virtual void Release() = 0;            // 釋放資源
};

4. 插件管理結構 PLUG_ST 與 CArray

typedef struct {
    CPlugBase* pObj;
    HINSTANCE  hIns;
} PLUG_ST, *LPPLUG_ST;

CArray m_arrPlugObj;

主程式實現關鍵步驟

1. 掃描並加載插件

CString strPath = ...\\Plugins;
CString strFind = strPath + _T("*.dll");
WIN32_FIND_DATA wfd;
HANDLE hf = FindFirstFile(strFind, &wfd);
if (hf != INVALID_HANDLE_VALUE) {
    do {
        CreatePlug(strPath + _T("\\") + wfd.cFileName);
    } while (FindNextFile(hf, &wfd));
    FindClose(hf);
}

2. CreatePlug 實現

void CreatePlug(LPCTSTR szPlug) {
    PLUG_ST st; ZeroMemory(&st, sizeof(st));
    st.hIns = LoadLibrary(szPlug);
    auto pFunc = (PFN_Plug_CreateObject)GetProcAddress(st.hIns, _T("Plug_CreateObject"));
    if (pFunc && pFunc((void**)&st.pObj))
        m_arrPlugObj.Add(st);
}

3. 工具欄按鈕動態創建

  • 建立圖片列表,將各插件 GetIcon() 返回的圖標加入。
  • 按鈕 ID 從 ID_PLUG_POINTER 起遞增,樣式 TBSTYLE_BUTTON。
  • 使用 ON_COMMAND_RANGE 映射命令範圍至 OnPlugHit。

4. 命令分發 OnPlugHit


void CMainFrame::OnPlugHit(UINT nID) {
    int id = nID - ID_PLUG_POINTER;
    if (id >= 0 && id < m_arrPlugObj.GetSize() && m_arrPlugObj[id].pObj)
        m_arrPlugObj[id].pObj->Interface(id);
}

5. 退出時資源釋放


for (int i = 0; i < m_arrPlugObj.GetSize(); ++i) {
    if (m_arrPlugObj[i].pObj) m_arrPlugObj[i].pObj->Release();
    if (m_arrPlugObj[i].hIns) FreeLibrary(m_arrPlugObj[i].hIns);
}
m_arrPlugObj.RemoveAll();

插件 DLL 製作要點

  • 專案類型:MFC Extension DLL 或 Regular DLL(靜態連結 MFC:Use MFC in a Static Library),確保資源內嵌。
  • 導出 Plug_CreateObject(.def 文件指定)。
  • 實現派生類 CPlugA : public CPlugBase,重寫虛函數;在 DllMain 或構造函數中 LoadIcon 並保存句柄,Release 時 DeleteObject。

總結

此架構實現了主程式與插件的完全解耦,支援無限擴展,且升級維護極為方便。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved