现在的位置: 首页 > 综合 > 正文

COM创建对象方法

2018年07月11日 ⁄ 综合 ⁄ 共 2972字 ⁄ 字号 评论关闭

1、创建COM组件的框架。(组件已注册)

IUnknown *pUnk = NULL;

IObject *pObject = NULL;

CoInitialize(NULL);

CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IDD_Unknown, (void**)&pUnk);

pUnk->QueryInterface(IID_IObject, (void**)&pObject);

pUnk->Release();

pObject->Func();

pObject->Release();
CoUninitialize();

 

CoCreateInstance的内部:

CoCreateInstance(....)
{
  .......
  IClassFactory *pClassFactory=NULL;

    //先获得类工厂对象①
  CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pClassFactory);

    //再通过类工厂对象创建组件并且得到IUnknown指针。②
  pClassFactory->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
  pClassFactory->Release();
  ........
}

 

//①-------------------

CoGetClassObject的内部:

CoGetClassObject(.....)
{
  //通过查注册表CLSID_Object,得知组件DLL的位置、文件名
  //使用LoadLibrary装入DLL库
  //使用函数GetProcAddress( "DllGetClassObject" )得到DLL库中函数DllGetClassObject的函数指针。
  //调用DllGetClassObject
}

DllGetClassObject是用来获得类工厂对象的,只有先得到类工厂才能去创建组件。

DllGetClassObject代码:
HRESULT_export  PASCAL DllGetClassObject (REFCLSID rclsid, REFIID riid, LPVOID * ppvObj)
{
    HRESULT hr = E_OUTOFMEMORY;
    *ppvObj = NULL;

    CClassFactory *pClassFactory = new CClassFactory(rclsid); //类工厂
    if (pClassFactory != NULL)   {
        hr = pClassFactory->QueryInterface(riid, ppvObj);
        pClassFactory->Release();
    }
    return hr;
}

//②----------------

CFactory::CreateInstance(.....)
{
  ...........
  CObject *pObject = new CObject; //组件对象
  pObject->QueryInterface(IID_IUnknown, (void**)&pUnk);
  pObject->Release();
  ...........
}

 

实例:

CComPtr<IAVIer> m_piAVIer;

m_piAVIer.CoCreateInstance(L"AVI.AVIer");

 

2、通过LoadLibrary和DllGetClassObject创建组件对象(组件未注册)

CComPtr<IAVIer> m_piAVIer;

typedef int (WINAPI *DllGetClassObjectPtr)(REFCLSID, REFIID, LPVOID*);

HMODULE hModule = LoadLibrary(dll文件路径);

//得到DllGetClassObject函数地址

DllGetClassObjectPtr ProcPtr = (DllGetClassObjectPtr)GetProcAddress(hModule, "DllGetClassObject");

CLSID rclsid;
IID riid;
::CLSIDFromString(A2W("{D5A365A3-44F8-47A0-8FCF-062372B1EB83}"), &rclsid);//类ID
::IIDFromString(A2W("{BE136856-CBEA-4079-A02B-BBC7A382BDB3}"), &riid);//接口ID

IClassFactory *pICF = NULL;//类工厂接口指针

ProcPtr(rclsid, IID_IClassFactory, (void**)(&pICF));//获取类工厂接口指针

//以上相当于①

pICF->CreateInstance(NULL, riid, (void**)&m_piAVIer);//创建COM对象

//以上相当于②

pICF->Release();

 

备注:

AVIer.rgs文件

HKCR
{
 Avi.AVIer.1 = s 'AVIer Class'
 {
  CLSID = s '{D5A365A3-44F8-47A0-8FCF-062372B1EB83}'
 }
 Avi.AVIer = s 'AVIer Class'
 {
  CLSID = s '{D5A365A3-44F8-47A0-8FCF-062372B1EB83}'
  CurVer = s 'Avi.AVIer.1'
 }
 NoRemove CLSID
 {
  ForceRemove {D5A365A3-44F8-47A0-8FCF-062372B1EB83} = s 'AVIer Class'
  {
   ProgID = s 'Avi.AVIer.1'
   VersionIndependentProgID = s 'Avi.AVIer'
   ForceRemove 'Programmable'
   InprocServer32 = s '%MODULE%'
   {
    val ThreadingModel = s 'Both'
   }
   'TypeLib' = s '{59AE79C3-3AC6-42E1-ABED-10B363EDAA4C}'
  }
 }
}

avi.idl文件

 [
  object,
  uuid(BE136856-CBEA-4079-A02B-BBC7A382BDB3),//接口ID
  dual,
  helpstring("IAVIer Interface"),
  pointer_default(unique)
 ]

 

library AVILib
{
 importlib("stdole32.tlb");
 importlib("stdole2.tlb");

 [
  uuid(D5A365A3-44F8-47A0-8FCF-062372B1EB83),//类ID
  helpstring("AVIer Class")
 ]
 coclass AVIer
 {
  [default] interface IAVIer;//类ID

 };
};

抱歉!评论已关闭.