Essential COM

, , , . . , , . , DllCanUnloadNow. , 3 , , , :

 // reasons to remain loaded //      LONG g_cLocks = 0; // called from AddRef + IClassFactory::LockServer(TRUE) //     AddRef + IClassFactory::LockServer(TRUE) void LockModule(void)   { InterlockedIncrement(&g_cLocks); } // called from Release + IClassFactory::LockServer(FALSE) //     Release + IClassFactory::LockServer(FALSE) void UnlockModule(void)   { InterlockedDecrement(&g_cLocks); } 

DllCanUnloadNow :

 STDAPI DllCanUnloadNow() { return g_cLocks ? S_FALSE : S_OK; } 

DllCanUnloadNow , " " CoFreeUnusedLibraries .

, - . - , . , " ", , . . Win32 Event, API- SetEvent:

 void UnlockModule(void) {     if (InterlockedDecrement(&g_cLocks) ==0) {         extern HANDLE g_heventShutdown;         SetEvent(g_heventShutdown);     } } 

Windows MSG, API- . PostThreadMessage WM_QUIT:

 void UnlockModule(void) {     if (InterlockedDecrement(&g_cLocks) == 0) {         extern DWORD g_dwMainThreadID;           // set from main thread           //                PostThreadMessage(g_dwMainThreadID, WNLQUIT,  , 0);     } } 

STA , , API- PostQuitMessage:

 void UnlockModule(void) {     if (InterlockedDecrement(&g_cLocks) == 0)         PostQuitMessage(0); } 

.

, . IClassFactory::LockServer(TRUE). .

, , . :

 STDMETHODIMP_(ULONG) MyClassObject::AddRef(void) {     LockModule();       // note outstanding reference       //          return 2;       // non-heap-based object       //  ,       " " } STDMETHODIMP_(ULONG) MyClassObject::Release(void) {     UnlockModule();       // note destroyed reference       //          return 1;       // non-heap-based object       //  ,       " " } 

, DLL , , Release .

, AddRef Release . , COM , , COM CoRegisterClassObject. , , COM . , . (self-imposed) CoRevokeClassObject. , CoRevokeClassObject , , , .

, AddRef Release:

 STDMETHODIMP_(ULONG) MyClassObject::AddRef(void) {       // ignore outstanding reference       //          return 2;       // non-heap-based object       //  ,       " " } STDMETHODIMP_(ULONG) MyClassObject::Release(void) {       // ignore destroyed reference       //          return 1;       // non-heap-based object       // ,       " " } 

, .

, , , . . , , . AddRef Release , COM . , SCM . CoMarshalInterface . IExternalConnection, , , . , IExternalConnection, o :

 STDMETHODIMP_(DWORD) MyClassObject::AddConnection(DWORD extconn, DWORD) {     DWORD res = 0;     if (extconn & EXTCONN_STRONG) {         LockModule();           // note external reference           //              res = InterlockedIncrement(&m_cExtRef);     }     return res; } STDMETHODIMP_(DWORD) MyClassObject::ReleaseConnection(DWORD extconn, DWORD,                                                        BOOL bLastReleaseKillsStub) {     DWORD res = 0;     if (extconn & EXTCONN_STRONG) {         UnlockModule();           // note external reference           //              res = InterlockedDecrement(&m_cExtRef);         if (res == 0 & bLastReleaseKillsStub)             CoDisconnectObject((IExternalConnection*)this, 0);     }     return res; } 

, , , , COM, .

IExternalConnection COM , . . LockServer IClassFactory, , . LockServer, . :

 IClassFactory *pcf = 0; HRESULT hr = CoGetClassObject(CLSID_You, CLSCTX_LOCAL_SERVER,                                , IID_IClassFactory, (void**)&pcf); if (SUCCEEDED(hr))     hr = pcf->LockServer(TRUE);       // keep server running?       //      ? 

COM . , CoGetClassObject IClassFactory::LockServer. . , LockServer. :

 IClassFactory *pcf = 0; HRESULT hr = S_OK; do {     if (pcf) pcf->Release();     hr = CoGetClassObject(CLSID_You, CLSCTX_LOCAL_SERVER,                           0, IID_IClassFactory, (void**)&pcf);     if (FAILED(hr))         break;     hr = pcf->LockServer(TRUE);       // keep server running?       //      ? } while (FAILED(hr)); 

, , LockServer . CoGetClassObject LockServer, LockServer , , . Windows NT 3.51 .

, IExternalConnection , COM Windows NT 4.0 . CoGetClass0bject SCM IClassFactory::LockServer. IClassFactory , COM . IClassFactory COM, Windows NT 4.0, IExternalConnection.

, . , , , (shutdown sequence) . CoRevokeClassObject . , , UnlockModule, . , , SetEvent PostThreadMessage, , , CoRevokeClassObject, . , , . COM API- :

 ULONG CoAddRefServerProcess(void); ULONG CoReleaseServerProcess(void); 

. COM, , . , CoReleaseServerProcess , , SCM, CLSID.

:

 void LockModule(void) {     CoAddRefServerProcess();       // COM maintains lock count       // COM      } void UnlockModule(void) {     if (CoReleaseServerProcess() == 0)         SetEvent(g_heventShutdown); } 

, - . .

CoAddRefServerProcess / CoReleaseServerProcess . , CoReleaseServerProcess RPC SCM. SCM , CoReleaseServerProcess COM, , , SCM (CO_E_SERVER_STOPPING). SCM , , . , COM, , CoReleaseServerProcess. , CO_E_SERVER_STOPPING IClassFactory::Create Instance, IPersistFile::Load , , - . :

 STDMETHODIMP MyClassObject::CreateInstance(IUnknown *puo,                                            REFIID riid, void **ppv) {     LockModule();       // ensure we don't shut down while in call       //      ,              //          HRESULT hr;     *ppv = 0;       // shutdown initiated?       //      ?     DWORD dw = WaitForSingleObject(g_heventShutdown, 0);     if (dw == WAIT_OBJECT_0)         hr = CO_E_SERVER_STOPPING;     else {           // normal CreateInstance implementation           //     CreateInstance     }     UnlockModule();     return hr; } 

COM .



Suschnost' tehnologii SOM
Essential COM
ISBN: 0201634465
EAN: 2147483647
Year: N/A
Pages: 103
Authors: Don Box

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net