1. 程式人生 > >在 DLL 中加入第二個 COM 類

在 DLL 中加入第二個 COM 類

引言

在前面幾篇文章裡,我們已經成功脫離ATL寫了一個COM元件,並且實現了自動化。今天,我們來加入第二個類,並且為加入第二個類做一些整理工作。

DLL建立一個Module

在前面,我們為了使得DllCanUnloadNow能正確工作而放了一個全域性變數LONG g_nModuleCount,並且在SampleClass的建構函式和解構函式裡對它進行自增和自減。另外還有個ITypeLib,也是全域性的。為了將這些零散的東西收集在一起,我們建立一個ComModule類,地位類似MFCCWinApp,作為這個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();