Automation In C++ Builder (轉)

worldblog發表於2007-12-14
Automation In C++ Builder (轉)[@more@]

  Automation:自動化,是基於COM技術的,它可以是其它應用的.ocx,或者單獨的exe,它有三種型別: 程式內伺服器,本地伺服器,程式伺服器,無論如何作為伺服器,它必須至少包含一個或多個供其它應用程式聯接和訪問的IDispatch介面,自動化伺服器可以沒有介面(UI).
a.程式內伺服器:它不可以單獨執行,沒有單獨的程式地址空間,準確地說它在自動化控制器的程式內執行,這類伺服器包括DLL,OCX.
b.本地伺服器:這類伺服器有自已的程式地址空間,但必須和自動化控制器同在一臺機器上執行.
c.程式伺服器:和本地伺服器一樣,它有自已的程式地空間,但它和自動化控制器不在同一臺機器上,它與自動化控制器位於不同的機器.
自動化伺服器和DLL的最大區別在於:自動化伺服器由於與語言的無關性,因此它只能使用有限的資料型別,而DLL在特定的語言環境中則可以使用任何資料型別.
  IDispatch介面是自動化伺服器的核心所在,也是自動化伺服器的機制,它是在不同語言工作下的介面,所謂自動化控制器就是使用IDispatch介面來訪問Automation伺服器的客戶,具體訪問過程:作為自動化控制器必須首先建立Automation伺服器物件,然後透過IUnknown介面中的QueryInterface方法獲得IDispatch介面指標,IDispatch介面透過內部的dispids結構來跟蹤伺服器中的屬性和方法,dispid是伺服器中每個屬性和方法的唯一標識,控制器透過IDispacth介面獲得每個屬性和方法的dispid後,就將它傳給
dispids結構,不過這個結構是在執行期有效(也就是說它們只能在執行期被訪問,具體地說在執行期間控制器透過GetIDSOfName來訪問該結構),所以這種訪問方式稱為後繫結.如果在編譯期間就可以訪問該結構就稱為前繫結,雙介面就屬於前繫結.
  雙介面(VTable Interface),也稱自定義介面,不過它的實現是由VTable(虛擬表),所以也叫VTable Interface,它的訪問速度要較IDispatch介面快,理由在於:VTable可以看作是一個虛擬函式列表,它的最初三個入口用於存放IUnknown(所有介面的基類)介面的三個函式的地址,(QueryInterface,AddRef,Release),緊接著就是IDispacth介面的四個函式的地址,其它的就存放伺服器各屬性和方法的地址,如果此時包含型別庫標頭檔案,那麼VTable可以從型別庫中獲取任一dispids結構,並在編譯期間就繫結在VTable外殼上(也就是TCOMI****),這樣就可以直接訪問VTable介面來訪問伺服器中的屬性和方法,從而避免IDispatch的GetIDSOfNames和Invoke方法,所以它的訪問速度要快於IDispacth介面,下面將寫一個簡單的伺服器和客戶端來作演示,我只貼出主要部分程式碼:
//Server:Written In September,2002
STDMETHODIMPL T****:: __fastcall GetData(BSTR *sList)
{
  TStrings *pList=new TStringList();
  try
  {
  TStrings *pList=new TStringList();
  TQuery *Query=new TQuery(NULL);
  Query->DatabaseName="all_ttmis";
  Query->Close();
  Query->->Clear();
  Query->SQL->Add(" * from A0");
  Query->Open();
  Query->First();
  while(!Query->Eof)
  {
  pList->Add(Query->FielyName("Specified Field")->AsString);
  Query->Next();
  }
  *sList=(WString)(pList->Text).Detach();
  Query->Close();
  delete pList;
  delete Query;
  }
  catch(Exception &E)
  {
  if(pList)
  {
  delete pList;
  }
  if(Query)
  {
  delete Query;
  }
  return Error(E.Message.c_str(),IID_IYourInterface);
  }
  return S_OK;
}

//Calling At Client

//Method 1:IDispacth Interface
void __fastcall TForm1::Button1Click(T *Sender)
{
  WideString S;
  IYourInterfaceDisp app;
  app.BindDefault();
  app.GetData(&S);
  TStrings *pList=new TStringList();
  pList->Text=String(S);
  for(int i=0;iCount;i++)
  {
  Memo1->Lines->Add(pList->Strings[i]);
  }
  app.Unbind();
  delete pList;
}

//Method 2:VTable Interface
void __fastcall TForm1::Button2Click(TObject *Sender)
{
  WideString S;
  TCOMIYourInterface app=CoYourInterface::Create();
  app->GetData(&S);
  TStrings *pList=new TStringList();
  pList->Text=String(S);
  for(int i=0;iCount;i++)
  {
  Memo1->Lines->Add(pList->Strings[i]);
  }
  delete pList; 
}

以上是本人對COM的理解,還望各位COM大俠指教.


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993457/,如需轉載,請註明出處,否則將追究法律責任。

相關文章