1.实现一个COM组件
1.)使用VC6建立Win32 Dll工程
2.)定义接口
interface IX : public IUnknown
{
        virtual HRESULT __stdcall FunX()=0;
};

interface IY : public IUnknown
{
        virtual HRESULT __stdcall FunY()=0;
};

interface IZ : public IUnknown
{
        virtual HRESULT __stdcall FunZ()=0;
};

extern "C" const CLSID CLSID_CA =    
    { 0xd7153f69, 0x9668, 0x47d7,    
    { 0xb9, 0xc8, 0xb2, 0x1a, 0x2b, 0xbe, 0xc5, 0x44 } };

// {2F8AD6CD-E631-4120-8F72-23C5E96921DE}
extern "C" const IID IID_IX =    
    { 0x2f8ad6cd, 0xe631, 0x4120,    
    { 0x8f, 0x72, 0x23, 0xc5, 0xe9, 0x69, 0x21, 0xde } } ;            

// {B6985A8F-6EA0-4a58-B3DC-9E14BCB81041}
extern "C" const IID IID_IY =    
    { 0xb6985a8f, 0x6ea0, 0x4a58,    
    { 0xb3, 0xdc, 0x9e, 0x14, 0xbc, 0xb8, 0x10, 0x41 } };

// {311FD901-390D-4fe1-AE83-96176D0A1991}
extern "C" const IID IID_IZ =    
    { 0x311fd901, 0x390d, 0x4fe1,    
    { 0xae, 0x83, 0x96, 0x17, 0x6d, 0xa, 0x19, 0x91 }};
3.)实现接口 IX,IY
class CA : public IX,public IY    
{
public:
        CA();
        virtual ~CA();

public:
        // Interface : IUnknown
        virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ;
        virtual ULONG __stdcall AddRef() ;
        virtual ULONG __stdcall Release() ;

        // Interface : IX
        virtual HRESULT __stdcall FunX();

        // Interface : IY
        virtual HRESULT __stdcall FunY();

private:
        long    m_lnRef ;
};

CA::CA()
{
        m_lnRef = 1 ;
        InterlockedIncrement(&g_lnClsRef) ;    
}

CA::~CA()
{
        InterlockedDecrement(&g_lnClsRef) ;    
}

HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv)    
{
        if(iid == IID_IUnknown)
        {
                *ppv = static_cast<IX *>(this) ;
        }
        else    if(iid == IID_IX)
        {
                *ppv = static_cast<IX *>(this) ;
        }
        else    if(iid == IID_IY)
        {
                *ppv = static_cast<IY *>(this) ;
        }
        else
        {
                *ppv = NULL ;
                return E_NOINTERFACE ;
        }

        reinterpret_cast<IUnknown*>(*ppv)->AddRef();

        return S_OK ;
}

ULONG __stdcall CA::AddRef()    
{
        return InterlockedIncrement(&m_lnRef) ;
}

ULONG __stdcall CA::Release()    
{
        if (InterlockedDecrement(&m_lnRef) == 0)
        {
                delete this ;
                return 0 ;
        }
        return m_lnRef ;
}
4.)实现IClassFactory
class CFactory : public IClassFactory    
{
public:
        CFactory();
        virtual ~CFactory();

public:
        // Interface : IUnknown
        virtual HRESULT __stdcall QueryInterface(
                        const IID& iid,
                        void** ppv
                        ) ;
                    
        virtual ULONG     __stdcall AddRef() ;
        virtual ULONG     __stdcall Release() ;

        // Interface : IClassFactory
        virtual HRESULT __stdcall CreateInstance(
                        IUnknown* pUnknownOuter,
                        const IID& iid,
                        void** ppv
                        ) ;

        virtual HRESULT __stdcall LockServer(BOOL bLock) ;    

private:
        long    m_lnRef ;
};

CFactory::CFactory()
{
        m_lnRef = 1 ;
}

CFactory::~CFactory()
{
}

// Interface : IUnknown
HRESULT __stdcall CFactory::QueryInterface(const IID& iid, void** ppv)    
{
        if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
        {
                *ppv = static_cast<IClassFactory*>(this) ;    
        }
        else
        {
                *ppv = NULL ;
                return E_NOINTERFACE ;
        }

        reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;

        return S_OK ;
}

ULONG     __stdcall CFactory::AddRef()    
{
        return InterlockedIncrement(&m_lnRef) ;
}

ULONG     __stdcall CFactory::Release()    
{
        if (InterlockedDecrement(&m_lnRef) == 0)
        {
                delete this ;
                return 0 ;
        }
    
        return m_lnRef ;
}

// Interface : IClassFactory
HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter,
                                                                 const IID& iid,
                                                                 void** ppv)    
{
        CA * pA = new CA ;
        if(pA == NULL)
        {
                return E_OUTOFMEMORY ;
        }

        HRESULT hRet = pA->QueryInterface(iid,ppv);

        pA->Release();

        return hRet ;
}

HRESULT __stdcall CFactory::LockServer(BOOL bLock)
{
        if (bLock)
        {
                InterlockedIncrement(&g_lnFacRef) ;    
        }
        else
        {
                InterlockedDecrement(&g_lnFacRef) ;
        }
        return S_OK ;
}
5.)实现注册类
    代码见附件.
 
6.)导出接口函数
STDAPI DllGetClassObject(
                        const CLSID& clsid, 
                        const IID& iid, 
                        void** ppv
                        )

        if (clsid != CLSID_CA) 
        { 
                return CLASS_E_CLASSNOTAVAILABLE ; 
        } 

        CFactory* pFactory = new CFactory ;     
        if (pFactory == NULL) 
        { 
                return E_OUTOFMEMORY ; 
        } 

        HRESULT hRet = pFactory->QueryInterface(iid, ppv) ; 
        pFactory->Release() ; 

        return hRet ;
}

STDAPI DllCanUnloadNow()

        if(g_lnClsRef == 0 && g_lnFacRef == 0) 
        { 
                return S_OK ; 
        } 
        else 
        { 
                return S_FALSE ; 
        }
}

//== Register Info===============================
LPCTSTR g_ptszName      = _T("PENGY Test Com.");
LPCTSTR g_ptszVerIndProgID  = _T("PENGY.Test");
LPCTSTR g_ptszProgID      = _T("PENGY.Test.1");
//== Register Info===============================

STDAPI DllRegisterServer()

        TCHAR  pszPath[1024]; 

        if(0 == GetModuleFileName(g_hmodSelf,pszPath,1024)) 
        { 
                return S_FALSE ; 
        } 

        // 将相关信息写入注册表. 
        return CRegisterAPI::RegisterServer( 
                                                pszPath, 
                                                CLSID_CA, 
                                                g_ptszName, 
                                                g_ptszVerIndProgID, 
                                                g_ptszProgID 
                                                ) ;

}

STDAPI DllUnregisterServer()

        // 删除相关的注册信息 
        return CRegisterAPI::UnregisterServer( 
                                              CLSID_CA, 
                                              g_ptszVerIndProgID, 
                                              g_ptszProgID 
                                              ) ;
}
7.)编译生成ComServer.dll
8.)注册和卸载
    注册:regsvr32 ComServer.dll
    卸载:regsvr32 /u ComServer.dll
9.)完成
 
2. 实现一个COM客户程序
1.)初始化COM
    CoInitialize(NULL);
2.)创建COM对象
IUnknown * pIUnknown = NULL ;
CoCreateInstance(
        CLSID_CA,    // 类ID 
        NULL,    // 聚合时使用 
        CLSCTX_INPROC_SERVER, // 组件类别(进程内组件) 
        IID_IUnknown, 
        (void**)& pIUnknown
);
3.)查询接口并使用接口提供的功能
IX * pIX = NULL ;
HRESULT hRet = pIUnknown->QueryInterface(IID_IX,(void**)&pIX);
if(SUCCEEDED(hRet))
{
        pIX->FunX() ; 
        // … 
        pIX->Release();
}
4.)卸载COM库
    CoUninitialize();