COM技术开发(一)

COM :基本的接口(IX,IY), 组件的实现(CA),以及对组件的调用

#include "pch.h"
#include <iostream>

#include <objbase.h>

using namespace std;

void trace(const char* msg) { cout << msg << endl; }

//Interfaces start
interface IX :IUnknown
{
        virtual void __stdcall Fx() = 0;
    };

interface IY :IUnknown
{
        virtual void __stdcall Fy() = 0;
    };

interface IZ :IUnknown
{
        virtual void __stdcall Fz() = 0;
    };

//Forward references for GUIDs
extern const IID IID_IX;
extern const IID IID_IY;
extern const IID IID_IZ;
//Interface end



//component start
class CA :public IX, public IY
{
        LONG m_cRef;
        virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv);
        virtual ULONG __stdcall AddRef();
        virtual ULONG __stdcall Release();
    
            virtual void __stdcall Fx() { cout << "Fx function" << endl; }
        virtual void __stdcall Fy() { cout << "Fy function" << endl; }
public:
        CA();
        ~CA() { trace("CA: Destory Self"); }
    };


CA::CA()
{
        trace("CA: Constrator Self");
        m_cRef = 0;
    }

HRESULT __stdcall CA::QueryInterface(const IID &iid, void **ppv)
{
        if (iid == IID_IUnknown)
            {
                trace("QueryInterface:Return pointer to IUnknown");
         * ppv = static_cast<IX*>(this);
            }
        else if (iid == IID_IX)
            {
                trace("QueryInterface:Return pointer to IX");
         * ppv = static_cast<IX*>(this);
            }
        else if (iid == IID_IY)
            {
                trace("QueryInterface:Return pointer to IX");
         * ppv = static_cast<IY*>(this);
            }
        else
            {
                trace("QueryInteface Interface not supported");
         * ppv = NULL;
                return E_NOINTERFACE;
            }
        reinterpret_cast<IUnknown*>(*ppv)->AddRef();
        return S_OK;
    }

ULONG __stdcall CA::AddRef()
{
        InterlockedIncrement(&m_cRef);
        cout << "CA AddRef -- Ref:" << m_cRef << endl;
        return m_cRef;
    }

ULONG __stdcall CA::Release()
{
    
            if (InterlockedDecrement(&m_cRef) == 0)
            {
                delete this;
                return 0;
            }
        cout << "CA ReleaseRef -- Ref:" << m_cRef << endl;
        return m_cRef;
    }

IUnknown* CreateInstance()
{
        IUnknown* pI = static_cast<IX*>(new CA);
        pI->AddRef();
        return pI;
    }

// {05464095-EC3A-45b3-8E0C-D1793FBDF13D}
static const IID IID_IX =
{ 0x5464095, 0xec3a, 0x45b3, { 0x8e, 0xc, 0xd1, 0x79, 0x3f, 0xbd, 0xf1, 0x3d } };

//  {39696224-3AE3-4b46-B056-99359CAC6CA9}
static const IID IID_IY =
{ 0x39696224, 0x3ae3, 0x4b46, { 0xb0, 0x56, 0x99, 0x35, 0x9c, 0xac, 0x6c, 0xa9 } };

// {6684A06D-64B8-46f3-9988-CDC119E18165}
static const IID IID_IZ =
{ 0x6684a06d, 0x64b8, 0x46f3, { 0x99, 0x88, 0xcd, 0xc1, 0x19, 0xe1, 0x81, 0x65 } };
//component end



//client start
int main(int argc, char* argv[])
{
        HRESULT hr;
        trace("Client:  Get an IUnknown pointer");
        IUnknown* pIUnknown = CreateInstance();
        IX* pIx = NULL;
        trace("Client: Get Interface IX");
        hr = pIUnknown->QueryInterface(IID_IX, (void**)&pIx);
        if (SUCCEEDED(hr))
            {
                trace("Client: Succeed Get Interface IX");
                pIx->Fx();
            }
    
            IY* pIY = NULL;
        hr = pIUnknown->QueryInterface(IID_IY, (void**)&pIY);
        pIUnknown->Release();
        if (SUCCEEDED(hr))
            {
                trace("Client: Succeed GetInterface IY");
                pIY->Fy();
                pIY->Release();
            }
    
            //Query IY from IX
            IY* pIYfromIX = NULL;
        hr = pIx->QueryInterface(IID_IY, (void**)&pIYfromIX);
        if (SUCCEEDED(hr))
            {
                trace("Client: Succeed GetInterfae IY from pIX");
                pIYfromIX->Fy();
                pIYfromIX->Release();
            }
        pIx->Release();
        //delete component
        //    delete pIUnknown;
            return 0;
    }
//client end

参考资料:

1、COM程序的简单实现(COM技术内幕笔记之一)

2、COM组件开发(一)—— 对象与接口

原文地址:https://www.cnblogs.com/2018shawn/p/10853975.html