在 DLL 中加入第二個 COM 類
引言
在前面幾篇文章裡,我們已經成功脫離ATL寫了一個COM元件,並且實現了自動化。今天,我們來加入第二個類,並且為加入第二個類做一些整理工作。
為DLL建立一個Module類
在前面,我們為了使得DllCanUnloadNow能正確工作而放了一個全域性變數LONG g_nModuleCount,並且在SampleClass的建構函式和解構函式裡對它進行自增和自減。另外還有個ITypeLib,也是全域性的。為了將這些零散的東西收集在一起,我們建立一個ComModule類,地位類似MFC的CWinApp,作為這個DLL中的唯一的全域性物件。
classComModule { public ComModule(HMODULEhModule = nullptr) : m_hModule(hModule), m_nGlobalRefCount(0), m_pTypeLib(nullptr) { TCHAR szModulePath[MAX_PATH] = {}; GetModuleFileName(m_hModule, szModulePath, ARRAYSIZE(szModulePath)); m_strModulePath = szModulePath; LoadTypeLib(szModulePath, &m_pTypeLib); } ~ComModule() { if (m_pTypeLib != nullptr) { m_pTypeLib->Release(); m_pTypeLib = nullptr; } } public: ULONG GlobalAddRef() { return (ULONG)InterlockedIncrement(&m_nGlobalRefCount); } ULONG GlobalRelease() { return (ULONG)InterlockedDecrement(&m_nGlobalRefCount); } private: HMODULEm_hModule; Stringm_strModulePath; LONGm_nGlobalRefCount; ITypeLib *m_pTypeLib; }; |
然後,定義一個全域性指標g_pComModule:
__declspec(selectany) ComModule *g_pComModule = nullptr; |
要求在DllMain裡面new/delete一個ComModule:
BOOLAPIENTRY DllMain(HMODULEhModule, DWORDul_reason_for_call, LPVOIDlpReserved) { switch (ul_reason_for_call) { caseDLL_PROCESS_ATTACH: g_pComModule = newComModule(hModule); break; caseDLL_THREAD_ATTACH: break; caseDLL_THREAD_DETACH: break; caseDLL_PROCESS_DETACH: delete g_pComModule; break; default: break; } returnTRUE; } |
再把全域性物件計數放到所有COM類的公共基類ComClass裡。
template <typenameT> classComClass { public: ComClass() { if (g_pComModule != nullptr) { g_pComModule->GlobalAddRef(); } } ~ComClass() { if (g_pComModule != nullptr) { g_pComModule->GlobalRelease();
|