調用dll和com的區別

來源:互聯網
上載者:User
問題:調用COM與調用DLL的區別和聯絡

調用DLL必須這樣:
HMODULE hDll=::LoadLibrary("..//Debug//wdll.dll");
if(hDll==NULL)
{
MessageBox("載入動態連結程式庫失敗","Warning",MB_OK|MB_ICONWARNING);
return;
}
typedef int (*Yadd)(int,int);
Yadd yadd=(Yadd)::GetProcAddress(hDll,"add");

而調用COM可以這樣:
#import "../debug/com.dll"
AfxOleInit();
IKeyComPtr keyCom;
HRESULT hr=keyCom.CreateInstance("DeviceCom.KeyMgr");
if( FAILED( hr)) ....

是不是這兩種DLL的調用的方法是固定的??有聯絡或統一的方法嗎?什麼時候用COM什麼時候用傳統的DLL?

回複:
不要把Dll和COM聯絡起來,更不要把COM看成是DLL,DLL只是用來裝載COM的,但是COM不一定要用DLL作載體,也可以用exe或者其他的,至於調用方法,這是specification規定的了。樓主先看看COM的基礎知識。
回複:
你說對了,他們的調用方法基本是固定的。

但是你要分清COM與DLL的概念。

回複:
兩種DLL可不可以都用傳統的調用方法來調用?不可以?為什麼?
回複:
com可以實現互操作,DLL不行
回複:
>>兩種DLL可不可以都用傳統的調用方法來調用?不可以?為什麼?
不可以!傳統的調用,是通過函數;
而COM組件的調用是通過介面.只有通過CreateInstance獲得介面指標,才可以使用該介面.所有的一切調用都是通過介面實現.
回複:
COM是更好的DLL,所以COM是可以通過傳統的DLL調用方法來實現的。
COM裡有一全域匯出函數
DllGetClassObject.
COM庫在載入COM組件時也是
LoadLibrary
GetProcAddress("DllGetClassObject")
開始的。
只不過COM把Dll所在路徑等等資訊把他註冊到註冊表裡了而已。

回複:
看看以下COM庫是怎樣幫我們把COM對象跑起來的吧。
  IUnknown *pUnk=NULL;
  IObject *pObject=NULL;
  CoInitialize(NULL);
  CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown, (void**)&pUnk);
  pUnk->QueryInterface(IID_IOjbect, (void**)&pObject);
  pUnk->Release();
  pObject->Func();
  pObject->Release();
  CoUninitialize();

  這就是一個典型的建立COM組件的架構,不過我的興趣在CoCreateInstance身上,讓我們來看看它內部做了一些什麼事情。以下是它內部實現的一個虛擬碼:

  CoCreateInstance(....)
  {
  .......
  IClassFactory *pClassFactory=NULL;
  CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pClassFactory);
  pClassFactory->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
  pClassFactory->Release();
  ........
  }

  這段話的意思就是先得到類廠對象,再通過類廠建立組件從而得到IUnknown指標。繼續深入一步,看看CoGetClassObject的內部偽碼:

 CoGetClassObject(.....)
 {
  //通過查註冊表CLSID_Object,得知組件DLL的位置、檔案名稱
  //裝入DLL庫
LoadLibrary
  //使用函數GetProcAddress( "DllGetClassObject" )得到DLL庫中函數DllGetClassObject的函數指標。
  //調用DllGetClassObject
 }
  DllGetClassObject是幹什麼的,它是用來獲得類廠對象的。只有先得到類廠才能去建立組件.
  下面是DllGetClassObject的偽碼:
  DllGetClassObject(...)
  {
  ......
  CFactory* pFactory= new CFactory; //類廠對象
  pFactory->QueryInterface(IID_IClassFactory, (void**)&pClassFactory);
  //查詢IClassFactory指標
  pFactory->Release();
 ......
  }
  CoGetClassObject的流程已經到此為止,現在返回CoCreateInstance,看看CreateInstance的偽碼:
  CFactory::CreateInstance(.....)
  {
  ...........
  CObject *pObject = new CObject; //組件對象
  pObject->QueryInterface(IID_IUnknown, (void**)&pUnk);
  pObject->Release();
  ...........
  }

所以,我們完全可以不註冊COM組件,而自己用以上相同的流程按照普通DLl的調用方式:
LoadLibary 和 GetProcAddress的方式 和對應的COM介面標頭檔,在加上COM dll產生的lib檔案把一個COM成功的調用起來的。

回複:
好,夠詳細的,慢慢消化一下,結:)
回複:/**
* DllGetClassObject函數原型聲明
*/
typedef int (CALLBACK *DllGetClassObjectPtr)(REFCLSID,REFIID,LPVOID *);
/**
* 從COM裡返回一介面對象,成功則返回true,否則返回false
*@param lpDll[in] : dll路徑
*@param strrclsid[in] : 類對象字串助記符
*@param strriid[in] : 介面對象字串助記符
*@param ppv [out] : 返回的介面對象
*/
int _stdcall GetComInterface( LPCSTR lpDll,LPCSTR strrclsid,LPCSTR strriid,LPVOID * ppv )
{
/**
* 載入DLL
*/
HINSTANCE hInstance = NULL ;
DllGetClassObjectPtr ProcFunc = NULL ;
bool bSucces = false;
hInstance = LoadLibrary(lpDll);

if ( hInstance )
{
/**
* 得到DllGetClassObject函數地址
*/
ProcFunc =(DllGetClassObjectPtr)GetProcAddress( hInstance, "DllGetClassObject");
if( ProcFunc )
{
/**
* 得到類GUID和介面的GUID
*/
CLSID rclsid;
IID riid;
CLSIDFromString((LPOLESTR )strrclsid,&rclsid);
if( strriid!= NULL )
{
CLSIDFromString((LPOLESTR )strriid,&riid);
}
else
{
riid=IID_IUnknown;
}

/***
* 得到類廠並建立介面對象
*/
IClassFactory *pIf = NULL;
if( ProcFunc(rclsid,IID_IClassFactory,(void **)&pIf)==S_OK )
{
bSucces = ( pIf->CreateInstance(NULL,riid,ppv)==S_OK );
pIf->Release();
pIf = NULL;
}
}

/**
* 如果建立借口對象失敗,釋放Dll
*/
if( !bSucces )
{
FreeLibrary( hInstance );
}
}

return bSucces ;

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.