执行出来的提示如下:其中有五处不知道为何调用,请大家帮忙指出,源代码在下面
1 Call CoCreateInstance to create//Client.cpp中的提示
2  component and get interface IX.//Client.cpp中的提示
//Client.cpp中在此处调用CoCreateInstance,此处内部自动调用(一)CoGetClassObject和(二)类厂的CreateInstance和(三)类厂的Release,可以参照MSDN中CoCreateInstance的帮助
//CoCreateInstance内部自动调用(一)CoGetClassObject,可以参照MSDN中CoCreateInstance的帮助
//CoCreateInstance内部自动调用(一)CoGetClassObject会内部自动调用(1)DllGetClassObject,可以参照MSDN中DllGetClassObject的帮助,如有其他可以指出此CoGetClassObject会自动调用DllGetClassObject,希望大家提出来
//CoCreateInstance内部自动调用(一)CoGetClassObject内部自动调用(1)DllGetClassObject,可以参照MSDN中DllGetClassObject的帮助
3 DllGetClassObject: Create class factory.//进入DllGetClassObject产生的提示
4 Class factory: Constructor self.//DllGetClassObject中创建类厂
5 Class factory:\t\tReturn pointer to IID_IUnknown IID_IClassFactory.//DllGetClassObject中调用类厂的QueryInterface产生的提示
6 Class factory: AddRef.//DllGetClassObject中调用类厂的QueryInterface中调用AddRef产生的提示
7 Class factory: Release.//DllGetClassObject中为刚创建的类厂调用Release产生的提示
//CoCreateInstance内部自动调用(二)类厂的CreateInstance,可以参照MSDN中CoCreateInstance的帮助
8 Class factory: Create component.//进入类厂的CreateInstance里产生的提示
9 Component: Constructor self.//类厂的CreateInstance创建组件
10 Component: Return pointer to IX.//类厂的CreateInstance调用组件的QueryInterface产生的提示
11 Component: AddRef.//类厂的CreateInstance调用组件的QueryInterface中调用AddRef产生的提示
12 Component: Release.//类厂的CreateInstance中为刚创建的组件调用Release产生的提示
//13 Component: AddRef.//不知道是怎么会调用AddRef产生的?????????
//14 Component: Release.//不知道是怎么会调用Release产生的?????????
//CoCreateInstance内部自动调用(三)类厂的Release,可以参照MSDN中CoCreateInstance的帮助
15 Class factory: Release.//调用类厂的Release产生的提示
16 Class factory: Destructor self.//调用类厂的Destructor产生的提示
//17 Component: Return pointer to IX.//不知道是怎么会调用QueryInterface产生的???????
//18 Component: AddRef.//不知道是怎么会调用AddRef产生的????????
//19 Component: Release.//不知道是怎么会调用Release产生的??????????
20 Succeeded getting IX.//Client.cpp中的提示
//Client.cpp中在此处调用Fx
21 Fx//调用组件中的Fx产生的提示
22 Ask for interface IY..//Client.cpp中的提示
//Client.cpp中在此处调用组件的QueryInterface
23 Component: Return pointer to IY.//组件的QueryInterface中的提示
24 Component: AddRef.//组件的QueryInterface中调用AddRef的提示
25 Succeeded getting IY..//Client.cpp中的提示
//Client.cpp中在此处调用Fy
26 Fy//调用组件中的Fy产生的提示
27 Component: Release.//调用组件Release的提示
28 Release IY interface..//Client.cpp中的提示
29 Ask for interface IZ..//Client.cpp中的提示
//Client.cpp中在此处调用组件的QueryInterface
30 Component: Return pointer to NULL.//组件的QueryInterface中的提示
31 Could not get interface IZ..//Client.cpp中的提示
32 Release IX interface..//Client.cpp中的提示
33 Component: Release.//调用组件Release的提示
34 Component: Destructor self.//调用组件Destructor的提示请大家帮忙解决上面不知道为何调用的五个地方

解决方案 »

  1.   

    源代码如下(六个文件):Client.cpp,CMPNT.cpp,IFace.h(Client.cpp,CMPNT.cpp中复用),GUIDS.CPP(Client.cpp,CMPNT.cpp中复用),Registry.h,Registry.cpp
    //
    // Client.cpp - client implementation
    //
    #include <iostream.h>
    #include <objbase.h>#include "Iface.h"void trace(const char* msg) { cout << "Client: \t\t" << msg << endl ;}//
    // main function
    //
    int main()
    {
    // Initialize COM Library
    CoInitialize(NULL) ; trace("Call CoCreateInstance to create") ;
    trace("  component and get interface IX.") ;
    IX* pIX = NULL ; 
    HRESULT hr = ::CoCreateInstance(CLSID_Component1,
                                    NULL, 
                                    CLSCTX_INPROC_SERVER,
                                    IID_IX, 
                                    (void**)&pIX) ;
    if (SUCCEEDED(hr))
    {
    trace("Succeeded getting IX.") ;
    pIX->Fx() ;          // Use interface IX. trace("Ask for interface IY.") ;
    IY* pIY = NULL ;
    hr = pIX->QueryInterface(IID_IY, (void**)&pIY) ;
    if (SUCCEEDED(hr))
    {
    trace("Succeeded getting IY.") ;
    pIY->Fy() ;       // Use interface IY.
    pIY->Release() ;
    trace("Release IY interface.") ;
    }
    else
    {
    trace("Could not get interface IY.") ;
    } trace("Ask for interface IZ.") ; IZ* pIZ = NULL ;
    hr = pIX->QueryInterface(IID_IZ, (void**)&pIZ) ;
    if (SUCCEEDED(hr))
    {
    trace("Succeeded in getting interface IZ.") ;
    pIZ->Fz() ;
    pIZ->Release() ;
    trace("Release IZ interface.") ;
    }
    else
    {
    trace("Could not get interface IZ.") ;
    } trace("Release IX interface.") ;
    pIX->Release() ;
    }
    else
    {
    cout << "Client: \t\tCould not create component. hr = "
         << hex << hr << endl ;    
    } // Uninitialize COM Library
    CoUninitialize() ; return 0 ;
    }
      

  2.   

    //
    // CMPNT.cpp : Defines the entry point for the DLL application.
    //#include "stdafx.h"
    #include <iostream.h>
    #include <objbase.h>
    #include "IFace.h"
    #include "Registry.h"// Trace function
    void trace(const char* msg) { cout << msg << endl ;}///////////////////////////////////////////////////////////
    //
    // Global variables
    //
    static HMODULE g_hModule = NULL ;   // DLL module handle
    static long g_cComponents = 0 ;     // Count of active components
    static long g_cServerLocks = 0 ;    // Count of locks// Friendly name of component
    const char g_szFriendlyName[] = "Inside COM, Chapter 7 Example" ;// Version-independent ProgID
    const char g_szVerIndProgID[] = "InsideCOM.Chap07" ;// ProgID
    const char g_szProgID[] = "InsideCOM.Chap07.1" ;
    ///////////////////////////////////////////////////////////
    //
    // Component 
    //
    class CA : public IX,
               public IY 
    {
    public:
    // IUnknown
    virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ;
    virtual ULONG __stdcall AddRef() ;
    virtual ULONG __stdcall Release() ; // Interface IX
    virtual void __stdcall Fx() { cout << "Fx" << endl ;} // Interface IY
    virtual void __stdcall Fy() { cout << "Fy" << endl ;}  // Constructor
    CA() ; // Destructor
    ~CA() ;private:
    // Reference count
    long m_cRef ;
    } ;
    //
    // Constructor
    //
    CA::CA() : m_cRef(1)

    InterlockedIncrement(&g_cComponents) ; 
    trace("Component:\t\tConstructor self.") ;
    }//
    // Destructor
    //
    CA::~CA() 

    InterlockedDecrement(&g_cComponents) ; 
    trace("Component:\t\tDestructor self.") ;
    }//
    // IUnknown implementation
    //
    HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv)
    {    
    if (iid == IID_IUnknown)
    {
    *ppv = static_cast<IX*>(this) ;
    trace("Component:\t\tReturn pointer to IID_IUnknown.") ;
    }
    else if (iid == IID_IX)
    {
    *ppv = static_cast<IX*>(this) ;
    trace("Component:\t\tReturn pointer to IX.") ; 
    }
    else if (iid == IID_IY)
    {
    *ppv = static_cast<IY*>(this) ; 
    trace("Component:\t\tReturn pointer to IY.") ; 
    }
    else
    {
    trace("Component:\t\tReturn pointer to NULL.") ; 
    *ppv = NULL ;
    return E_NOINTERFACE ;
    }
    reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
    return S_OK ;
    }ULONG __stdcall CA::AddRef()
    {
    trace("Component:\t\tAddRef.") ;
    return InterlockedIncrement(&m_cRef) ;
    }ULONG __stdcall CA::Release() 
    {
    trace("Component:\t\tRelease.") ;
    if (InterlockedDecrement(&m_cRef) == 0)
    {
    delete this ;
    return 0 ;
    }
    return m_cRef ;
    }
    ///////////////////////////////////////////////////////////
    //
    // Class factory
    //
    class CFactory : public IClassFactory
    {
    public:
    // 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) ;  // Constructor
    CFactory() : m_cRef(1) {trace("Class factory:\t\tConstructor self.") ;} // Destructor
    ~CFactory() { trace("Class factory:\t\tDestructor self.") ;}private:
    long m_cRef ;
    } ;//
    // Class factory IUnknown implementation
    //
    HRESULT __stdcall CFactory::QueryInterface(const IID& iid, void** ppv)
    {    
    if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
    {
    *ppv = static_cast<IClassFactory*>(this) ; 
    trace("Class factory:\t\tReturn pointer to IID_IUnknown IID_IClassFactory.") ;
    }
    else
    {
    trace("Class factory:\t\tReturn pointer to NULL.") ;
    *ppv = NULL ;
    return E_NOINTERFACE ;
    }
    reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
    return S_OK ;
    }ULONG __stdcall CFactory::AddRef()
    {
    trace("Class factory:\t\tAddRef.") ;
    return InterlockedIncrement(&m_cRef) ;
    }ULONG __stdcall CFactory::Release() 
    {
    trace("Class factory:\t\tRelease.") ;
    if (InterlockedDecrement(&m_cRef) == 0)
    {
    delete this ;
    return 0 ;
    }
    return m_cRef ;
    }//
    // IClassFactory implementation
    //
    HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter,
                                               const IID& iid,
                                               void** ppv) 
    {
    trace("Class factory:\t\tCreate component.") ; // Cannot aggregate.
    if (pUnknownOuter != NULL)
    {
    return CLASS_E_NOAGGREGATION ;
    } // Create component.
    CA* pA = new CA ;
    if (pA == NULL)
    {
    return E_OUTOFMEMORY ;
    } // Get the requested interface.
    HRESULT hr = pA->QueryInterface(iid, ppv) ; // Release the IUnknown pointer.
    // (If QueryInterface failed, component will delete itself.)
    pA->Release() ;
    return hr ;
    }// LockServer
    HRESULT __stdcall CFactory::LockServer(BOOL bLock) 
    {
    if (bLock)
    {
    InterlockedIncrement(&g_cServerLocks) ; 
    }
    else
    {
    InterlockedDecrement(&g_cServerLocks) ;
    }
    return S_OK ;
    }
    ///////////////////////////////////////////////////////////
    //
    // Exported functions
    ////
    // Can DLL unload now?
    //
    ///////////////////////////////////////////////////////////
    //
    // DLL module information
    //
    BOOL APIENTRY DllMain(HANDLE hModule,
                          DWORD dwReason,
                          void* lpReserved)
    {
    if (dwReason == DLL_PROCESS_ATTACH)
    {
    g_hModule = (HMODULE)hModule ;
    }
    return TRUE ;
    }
    STDAPI DllCanUnloadNow()
    {
    if ((g_cComponents == 0) && (g_cServerLocks == 0))
    {
    return S_OK ;
    }
    else
    {
    return S_FALSE ;
    }
    }//
    // Get class factory
    //
    extern "C" HRESULT __stdcall DllGetClassObject(const CLSID& clsid,
                             const IID& iid,
                             void** ppv)
    {
    trace("DllGetClassObject:\tCreate class factory.") ; // Can we create this component?
    if (clsid != CLSID_Component1)
    {
    return CLASS_E_CLASSNOTAVAILABLE ;
    } // Create class factory.
    CFactory* pFactory = new CFactory ;  // No AddRef in constructor
    if (pFactory == NULL)
    {
    return E_OUTOFMEMORY ;
    } // Get requested interface.
    HRESULT hr = pFactory->QueryInterface(iid, ppv) ;
    pFactory->Release() ; return hr ;
    }//
    // Server registration
    //
    extern "C" HRESULT __stdcall  DllRegisterServer()
    {
    return RegisterServer(g_hModule, 
                          CLSID_Component1,
                          g_szFriendlyName,
                          g_szVerIndProgID,
                          g_szProgID) ;
    }
    //
    // Server unregistration
    //
    extern "C" HRESULT __stdcall DllUnregisterServer()
    {
    return UnRegisterServer(CLSID_Component1,
                            g_szVerIndProgID,
                            g_szProgID) ;
    }
      

  3.   

    //
    // Iface.h - 
    //    Declarations of interfaces, IIDs, and CLSID
    //    shared by the client and the component.
    //
    interface IX : IUnknown
    {
    virtual void pascal Fx() = 0 ;
    };
    interface IY : IUnknown
    {
    virtual void pascal Fy() = 0 ;
    };
    interface IZ : IUnknown
    {
    virtual void pascal Fz() = 0 ;
    };//
    // Declaration of GUIDs for interfaces and component.
    //   These constants are defined in GUIDs.cpp.
    //
    extern "C" const IID IID_IX ;
    extern "C" const IID IID_IY ;
    extern "C" const IID IID_IZ ;extern "C" const CLSID CLSID_Component1 ;
    //
    // GUIDs.cpp
    //   - Defines all IIDs and CLSIDs for the client and the component.
    //     The declaration of these GUIDs is in Iface.h
    //
    #include "stdafx.h"
    #include <objbase.h>// {32bb8320-b41b-11cf-a6bb-0080c7b2d682}
    extern "C" const IID IID_IX = 
    {0x32bb8320, 0xb41b, 0x11cf,
    {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;// {32bb8321-b41b-11cf-a6bb-0080c7b2d682}
    extern "C" const IID IID_IY = 
    {0x32bb8321, 0xb41b, 0x11cf,
    {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;// {32bb8322-b41b-11cf-a6bb-0080c7b2d682}
    extern "C" const IID IID_IZ = 
    {0x32bb8322, 0xb41b, 0x11cf,
    {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;// {0c092c21-882c-11cf-a6bb-0080c7b2d682}
    extern "C" const CLSID CLSID_Component1 =
    {0x0c092c21, 0x882c, 0x11cf,
    {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;
      

  4.   

    谢谢楼上的,有些是内部自动调用的,我跟进去也看不明白啊
    //
    // Registry.h
    //   - Helper functions registering and unregistering a component.
    //
    #ifndef __Registry_H__
    #define __Registry_H__// This function will register a component in the Registry.
    // The component calls this function from its DllRegisterServer function.
    HRESULT RegisterServer(HMODULE hModule, 
                           const CLSID& clsid, 
                           const char* szFriendlyName,
                           const char* szVerIndProgID,
                           const char* szProgID) ;// This function will unregister a component.  Components
    // call this function from their DllUnregisterServer function.
    HRESULT UnRegisterServer(const CLSID& clsid,
                             const char* szVerIndProgID,
                             const char* szProgID) ;#endif
    //
    // Registry.cpp
    //#include "stdafx.h"
    #include <objbase.h>
    #include <assert.h>#include "Registry.h"////////////////////////////////////////////////////////
    //
    // Internal helper functions prototypes
    //// Set the given key and its value.
    BOOL SetKeyAndValue(const char* szKey,
                        const char* szSubKey,
                        const char* szValue) ;// Convert a CLSID into a char string.
    void CLSIDtochar(const CLSID& clsid, 
                     char* szCLSID,
                     int iLength) ;// Delete szKeyChild and all of its descendents.
    LONG RecursiveDeleteKey(HKEY hKey, const char* szSubKey) ;////////////////////////////////////////////////////////
    //
    // Constants
    //// Size of a CLSID as a string
    const int CLSID_STRING_SIZE = 39 ;/////////////////////////////////////////////////////////
    //
    // Public function implementation
    ////
    // Register the component in the registry.
    //
    HRESULT RegisterServer(HMODULE hModule,            // DLL module handle
                           const CLSID& clsid,         // Class ID
                           const char* szFriendlyName, // Friendly Name
                           const char* szVerIndProgID, // Programmatic
                           const char* szProgID)       //   IDs
    {
    // Get server location.
    char szModule[512] ;
    DWORD dwResult =
    ::GetModuleFileName(hModule, 
                        szModule,
                        sizeof(szModule)/sizeof(char)) ;
    assert(dwResult != 0) ; // Convert the CLSID into a char.
    char szCLSID[CLSID_STRING_SIZE] ;
    CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ; // Build the key CLSID\\{...}
    char szKey[64] ;
    strcpy(szKey, "CLSID\\") ;
    strcat(szKey, szCLSID) ;
      
    // Add the CLSID to the registry.
    SetKeyAndValue(szKey, NULL, szFriendlyName) ; // Add the server filename subkey under the CLSID key.
    SetKeyAndValue(szKey, "InprocServer32", szModule) ; // Add the ProgID subkey under the CLSID key.
    SetKeyAndValue(szKey, "ProgID", szProgID) ; // Add the version-independent ProgID subkey under CLSID key.
    SetKeyAndValue(szKey, "VersionIndependentProgID",
                   szVerIndProgID) ; // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
    SetKeyAndValue(szVerIndProgID, NULL, szFriendlyName) ; 
    SetKeyAndValue(szVerIndProgID, "CLSID", szCLSID) ;
    SetKeyAndValue(szVerIndProgID, "CurVer", szProgID) ; // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
    SetKeyAndValue(szProgID, NULL, szFriendlyName) ; 
    SetKeyAndValue(szProgID, "CLSID", szCLSID) ; return S_OK ;
    }//
    // Remove the component from the registry.
    //
    HRESULT UnRegisterServer(const CLSID& clsid,         // Class ID
     const char* szVerIndProgID, // Programmatic
     const char* szProgID)       //   IDs
    {
    // Convert the CLSID into a char.
    char szCLSID[CLSID_STRING_SIZE] ;
    CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ; // Build the key CLSID\\{...}
    char szKey[64] ;
    strcpy(szKey, "CLSID\\") ;
    strcat(szKey, szCLSID) ; // Delete the CLSID Key - CLSID\{...}
    LONG lResult = RecursiveDeleteKey(HKEY_CLASSES_ROOT, szKey) ;
    assert((lResult == ERROR_SUCCESS) ||
           (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist. // Delete the version-independent ProgID Key.
    lResult = RecursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID) ;
    assert((lResult == ERROR_SUCCESS) ||
           (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist. // Delete the ProgID key.
    lResult = RecursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID) ;
    assert((lResult == ERROR_SUCCESS) ||
           (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist. return S_OK ;
    }///////////////////////////////////////////////////////////
    //
    // Internal helper functions
    //// Convert a CLSID to a char string.
    void CLSIDtochar(const CLSID& clsid,
                     char* szCLSID,
                     int length)
    {
    assert(length >= CLSID_STRING_SIZE) ;
    // Get CLSID
    LPOLESTR wszCLSID = NULL ;
    HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
    assert(SUCCEEDED(hr)) ; // Covert from wide characters to non-wide.
    wcstombs(szCLSID, wszCLSID, length) ; // Free memory.
    CoTaskMemFree(wszCLSID) ;
    }//
    // Create a key and set its value.
    //   - This helper function was borrowed and modifed from
    //     Kraig Brockschmidt's book Inside OLE.
    //
    BOOL SetKeyAndValue(const char* szKey,
                        const char* szSubkey,
                        const char* szValue)
    {
    HKEY hKey;
    char szKeyBuf[1024] ; // Copy keyname into buffer.
    strcpy(szKeyBuf, szKey) ; // Add subkey name to buffer.
    if (szSubkey != NULL)
    {
    strcat(szKeyBuf, "\\") ;
    strcat(szKeyBuf, szSubkey ) ;
    } // Create and open key and subkey.
    long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,
                                  szKeyBuf, 
                                  0, NULL, REG_OPTION_NON_VOLATILE,
                                  KEY_ALL_ACCESS, NULL, 
                                  &hKey, NULL) ;
    if (lResult != ERROR_SUCCESS)
    {
    return FALSE ;
    } // Set the Value.
    if (szValue != NULL)
    {
    RegSetValueEx(hKey, NULL, 0, REG_SZ, 
                  (BYTE *)szValue, 
                  strlen(szValue)+1) ;
    } RegCloseKey(hKey) ;
    return TRUE ;
    }//
    // Delete a key and all of its descendents.
    //
    LONG RecursiveDeleteKey(HKEY hKey,           // Parent of key to delete
                            const char* szSubKey)  // Key to delete
    {
    // Open the child.
    HKEY hSubKey ;
    LONG lRes = RegOpenKeyEx(hKey, szSubKey, 0,
                             KEY_ALL_ACCESS, &hSubKey) ;
    if (lRes != ERROR_SUCCESS)
    {
    return lRes ;
    } // Enumerate all of the decendents of this child.
    FILETIME time ;
    char szBuffer[256] ;
    DWORD dwSize = 256 ;
    while (RegEnumKeyEx(hSubKey, 0, szBuffer, &dwSize, NULL,
                        NULL, NULL, &time) == S_OK)
    {
    // Delete the decendents of this child.
    lRes = RecursiveDeleteKey(hSubKey, szBuffer) ;
    if (lRes != ERROR_SUCCESS)
    {
    // Cleanup before exiting.
    RegCloseKey(hSubKey) ;
    return lRes;
    }
    dwSize = 256 ;
    } // Close the child.
    RegCloseKey(hSubKey) ; // Delete this child.
    return RegDeleteKey(hKey, szSubKey) ;
    }
      

  5.   

    //13 Component: AddRef.//不知道是怎么会调用AddRef产生的?????????
    //14 Component: Release.//不知道是怎么会调用Release产生的?????????
    我跟进去发现两个是连续调用,好象没有什么意义啊
    //17 Component: Return pointer to IX.//不知道是怎么会调用QueryInterface产生的???????
    //18 Component: AddRef.//不知道是怎么会调用AddRef产生的????????
    //19 Component: Release.//不知道是怎么会调用Release产生的??????????
    再次调用QueryInterface,其实上面已经调用过了,为什么还要再次调用,如果这个找到理由,后面两个提示也就不是问题了
      

  6.   

    Client.cpp是客户端程序,用到Iface.h,GUIDs.cpp这两个文件,CMPNT.cpp是COM程序,用到Registry.h,Registry.cpp,Iface.h,GUIDs.cpp这4个文件
      

  7.   

    Client call CoCreateInitstance->
    ->DllGetClassObject->CoGetClassObject->Factory的CreateInstance->COM本身的QueryInterface大体上好像就是这几个函数在起作用,其中可能还涉及到base class 和 derive class的构造 析构顺序以及 virtual function的call,把这几个仔细理解一下应该不难找出其执行顺序