COM technology insider Reading Notes-Chapter 1 reference count

Source: Internet
Author: User

This chapter describes the two counting functions-addref and release-of the iunknow interface that must be implemented by com. In short, this is similar to smart pointer functions. The memory is allocated in the component class. When the pointer of the component class is passed out, the reference is added. When the outgoing pointer is used up, the reference count is reduced. The memory is released when the reference count is reduced to 0.

Note that addref, such as QueryInterface and createinstance, should be added to common function implementations. The book emphasizes the lifecycle of objects, which is exactly the purpose of the two functions.

For this chapter, because I have no experience using COM in large program code at present, although I feel that the lifecycle is important, I don't have much profound experience. In addition, the methods described in the book may make people feel tired. We recommend that you skip this step for beginners. I learned this way.

To correctly use the reference count, you need to understand the following three simple rules:

1. Call addref before returning. for functions that return interface pointers, call addref with corresponding pointers before returning. These functions include QueryInterface and createinstance. In this way, when the customer obtains an interface from this function, it does not need to call addref.

2. After using these interfaces, release.

3. Call addref after assigning values. When you assign an interface pointer to another interface pointer, you should call addref. That is, the reference count of the corresponding component should be added after another reference of the interface is created.

When we use smart pointers to completely encapsulate the reference count, programmers can almost forget the reference count problem.

//// RefCount.cpp// To compile, use: cl RefCount.cpp UUID.lib//#include <iostream.h>#include <objbase.h>void trace(const char* msg) { cout << msg << endl ;}// Forward references for GUIDsextern const IID IID_IX ;extern const IID IID_IY ;extern const IID IID_IZ ;// Interfacesinterface IX : IUnknown{virtual void __stdcall Fx() = 0 ;} ;interface IY : IUnknown{virtual void __stdcall Fy() = 0 ;} ;interface IZ : IUnknown{virtual void __stdcall Fz() = 0 ;} ;//// Component//class CA : public IX,           public IY{// IUnknown implementationvirtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ;virtual ULONG __stdcall AddRef() ;virtual ULONG __stdcall Release() ;// Interface IX implementationvirtual void __stdcall Fx() { cout << "Fx" << endl ;}// Interface IY implementationvirtual void __stdcall Fy() { cout << "Fy" << endl ;}public:// ConstructorCA() : m_cRef(0) {}// Destructor~CA() { trace("CA:     Destroy self.") ;}private:long m_cRef;} ;HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv){ if (iid == IID_IUnknown){trace("CA QI:  Return pointer to IUnknown.") ;*ppv = static_cast<IX*>(this) ;} else if (iid == IID_IX){trace("CA QI:  Return pointer to IX.") ;*ppv = static_cast<IX*>(this) ;}else if (iid == IID_IY){trace("CA QI:  Return pointer to IY.") ;*ppv = static_cast<IY*>(this) ;}else{     trace("CA QI:  Interface not supported.") ;*ppv = NULL ;return E_NOINTERFACE;}reinterpret_cast<IUnknown*>(*ppv)->AddRef() ; return S_OK ;}ULONG __stdcall CA::AddRef(){cout << "CA:     AddRef = " << m_cRef+1 << '.' << endl ;return InterlockedIncrement(&m_cRef) ;}ULONG __stdcall CA::Release() {cout << "CA:     Release = " << m_cRef-1 << '.' << endl ;if (InterlockedDecrement(&m_cRef) == 0){delete this ;return 0 ;}return m_cRef ;}//// Creation function//IUnknown* CreateInstance(){IUnknown* pI = static_cast<IX*>(new CA) ;pI->AddRef() ;return pI ;}//// IIDs//// {32bb8320-b41b-11cf-a6bb-0080c7b2d682}static const IID IID_IX = {0x32bb8320, 0xb41b, 0x11cf,{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;// {32bb8321-b41b-11cf-a6bb-0080c7b2d682}static const IID IID_IY = {0x32bb8321, 0xb41b, 0x11cf,{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;// {32bb8322-b41b-11cf-a6bb-0080c7b2d682}static const IID IID_IZ = {0x32bb8322, 0xb41b, 0x11cf,{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;//// Client//int main(){HRESULT hr ;trace("Client: Get an IUnknown pointer.") ;IUnknown* pIUnknown = CreateInstance() ;trace("Client: Get interface IX.") ;IX* pIX = NULL ; hr = pIUnknown->QueryInterface(IID_IX, (void**)&pIX) ;if (SUCCEEDED(hr)){trace("Client: Succeeded getting IX.") ;pIX->Fx() ;          // Use interface IX.pIX->Release() ;}trace("Client: Get interface IY.") ;IY* pIY = NULL ;hr = pIUnknown->QueryInterface(IID_IY, (void**)&pIY) ;if (SUCCEEDED(hr)){trace("Client: Succeeded getting IY.") ;pIY->Fy() ;          // Use interface IY.pIY->Release() ;}trace("Client: Ask for an unsupported interface.") ;IZ* pIZ = NULL ;hr = pIUnknown->QueryInterface(IID_IZ, (void**)&pIZ) ;if (SUCCEEDED(hr)){trace("Client: Succeeded in getting interface IZ.") ;pIZ->Fz() ;pIZ->Release() ;}else{trace("Client: Could not get interface IZ.") ;}trace("Client: Release IUnknown interface.") ;pIUnknown->Release() ;return 0;}

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.