準(zhǔn)備及條件:
COM服務(wù)器為進(jìn)程內(nèi)服務(wù)器,DLL名為simpCOM.dll,該組件只有一個(gè)接口IFoo,該接口只有一個(gè)方法HRESULT SayHello(void)
在SDK中調(diào)用
=====================================
一、最簡(jiǎn)單最常用的一種,用#import導(dǎo)入類型庫(kù),利用VC提供的智能指針包裝類
演示代碼:
#import "D:\Temp\vc\simpCOM\Debug\simpCOM.dll" no_namespace
CoInitialize(NULL);
IFooPtr spFoo = NULL;
spFoo.CreateInstance(__uuidof(Foo));
spFoo->SayHello();
spFoo.Release();/*暈死了,本來智能指針就是為了讓用戶不用關(guān)心這個(gè)的,可是我發(fā)現(xiàn)如果不手工調(diào)用一下的話,程序退出后會(huì)發(fā)生內(nèi)存訪問錯(cuò)誤,我是在console中做試驗(yàn)的,哪位大俠知道怎么回事請(qǐng)一定指教*/
CoUninitialize();
二、引入midl.exe產(chǎn)生的*.h,*_i.c文件,利用CoCreateInstance函數(shù)來調(diào)用
演示代碼:
/*在工程中加入*_i.c文件,例如本例的simpCOM_i.c,該文件定義了類和接口的guid值,如果不引入的話,會(huì)發(fā)生連接錯(cuò)誤。*/
#include "D:\Temp\vc\simpCOM\simpCOM.h"
CoInitialize(NULL);
IFoo* pFoo = NULL;
HRESULT hr = CoCreateInstance(CLSID_Foo, NULL, CLSCTX_ALL, IID_IFoo, (void**)&pFoo);
if (SUCCEEDED(hr) && (pFoo != NULL))
{
pFoo->SayHello();
pFoo->Release();
}
CoUninitialize();
三、不用CoCreateInstance,直接用CoGetClassObejct得到類廠對(duì)象接口,然后用該接口的方法CreateInstance來生成實(shí)例。
演示代碼:
/*前期準(zhǔn)備如二方法所述*/
IClassFactory* pcf = NULL;
HRESULT hr = CoGetClassObject(CLSID_Foo, CLSCTX_ALL, NULL, IID_IClassFactory, (void**)&pcf);
if (SUCCEEDED(hr) && (pcf != NULL))
{
IFoo* pFoo = NULL;
hr = pcf->CreateInstance(NULL, IID_IFoo, (void**)&pFoo);
if (SUCCEEDED(hr) && (pFoo != NULL))
{
pFoo->SayHello();
pFoo->Release();
}
pcf->Release();
}
四、不用CoCreateInstance or CoGetClassObject,直接從dll中得到DllGetClassObject,接著生成類對(duì)象及類實(shí)例(本方法適合于你想用某個(gè)組件,卻不想在注冊(cè)表中注冊(cè)該組件)
演示代碼:
/*前期準(zhǔn)備工作如二方法所述,事實(shí)上只要得到CLSID和IID的定義及接口的定義就行*/
typedef HRESULT (__stdcall * pfnGCO) (REFCLSID, REFIID, void**);
pfnGCO fnGCO = NULL;
HINSTANCE hdllInst = LoadLibrary("D:\\Temp\\vc\\simpCOM\\Debug\\simpCOM.dll");
fnGCO = (pfnGCO)GetProcAddress(hdllInst, "DllGetClassObject");
if (fnGCO != 0)
{
IClassFactory* pcf = NULL;
HRESULT hr=(fnGCO)(CLSID_Foo, IID_IClassFactory, (void**)&pcf);
if (SUCCEEDED(hr) && (pcf != NULL))
{
IFoo* pFoo = NULL;
hr = pcf->CreateInstance(NULL, IID_IFoo, (void**)&pFoo);
if (SUCCEEDED(hr) && (pFoo != NULL))
{
pFoo->SayHello();
pFoo->Release();
}
pcf->Release();
}
}
FreeLibrary(hdllInst);
在MFC中調(diào)用
=====================================
在MFC中除了上面的幾種方法外,還有一種更方便的方法,就是通過ClassWizard利用類型庫(kù)生成包裝類,不過有個(gè)前提就是com組件的接口必須是派生自IDispatch
具體方法:
1、按Ctrl+W調(diào)出類向?qū)В碅dd Class按鈕彈出新菜單,選From a type libarary,然后定位到simpCOM.dll,接下來會(huì)出來該simpCOM中的所有接口,選擇你想生成的接口包裝類后,向?qū)?huì)自動(dòng)生成相應(yīng)的.cpp和.h文件.
這樣你就可以在你的MFC工程中像使用普通類那樣使用COM組件了.
演示代碼:
CoInitialize(NULL);
IFoo foo;
if (foo.CreateDispatch("simpCOM.Foo") != 0)
{
foo.SayHello();
foo.ReleaseDispatch();
}
CoUninitialize();
可以下載代碼測(cè)試
ATLEVENT
InvokeComTest