天天看點

VC調用COM元件

常用的SDK開發包常以COM元件提供,嘉盈短信二次開發包也是一個COM元件. 下面通過例子介紹在VC中如何調用COM元件.

準備及條件:

COM伺服器為程序内伺服器,DLL名為simpCOM.dll,該元件隻有一個接口IFoo,該接口隻有一個方法HRESULT SayHello(void)

在SDK中調用

=====================================

一、最簡單最常用的一種,用#import導入類型庫,利用VC提供的智能指針包裝類

示範代碼:

#import "D:\Temp\vc\simpCOM\Debug\simpCOM.dll" no_namespace

CoInitialize(NULL);

IFooPtr spFoo = NULL;

spFoo.CreateInstance(__uuidof(Foo));

spFoo->SayHello();

spFoo.Release();/*暈死了,本來智能指針就是為了讓使用者不用關心這個的,可是我發現如果不手工調用一下的話,程式退出後會發生記憶體通路錯誤,我是在console中做試驗的,哪位大俠知道怎麼回事請一定指教*/

CoUninitialize();

二、引入midl.exe産生的*.h,*_i.c檔案,利用CoCreateInstance函數來調用

示範代碼:

/*在工程中加入*_i.c檔案,例如本例的simpCOM_i.c,該檔案定義了類和接口的guid值,如果不引入的話,會發生連接配接錯誤。*/

#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得到類廠對象接口,然後用該接口的方法CreateInstance來生成執行個體。

示範代碼:

/*前期準備如二方法所述*/

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,接着生成類對象及類執行個體(本方法适合于你想用某個元件,卻不想在系統資料庫中注冊該元件)

示範代碼:

/*前期準備工作如二方法所述,事實上隻要得到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中調用

=====================================

在MFC中除了上面的幾種方法外,還有一種更友善的方法,就是通過ClassWizard利用類型庫生成包裝類,不過有個前提就是com元件的接口必須是派生自IDispatch

具體方法:

1、按Ctrl+W調出類向導,按Add Class按鈕彈出新菜單,選From a type libarary,然後定位到simpCOM.dll,接下來會出來該simpCOM中的所有接口,選擇你想生成的接口包裝類後,向導會自動生成相應的.cpp和.h檔案.

這樣你就可以在你的MFC工程中像使用普通類那樣使用COM元件了.

示範代碼:

       CoInitialize(NULL);

       IFoo foo;

       if (foo.CreateDispatch("simpCOM.Foo") != 0)

       {

              foo.SayHello();

              foo.ReleaseDispatch();

繼續閱讀