Request對象內幕--如何通過IDispatch接口返回BSTR字符串

在ASP開發中,我們經常會用到類似這樣的調用 oUserName=Request("UserName")。可以肯定的是,我們需要得到的是一個字符串值,事實上,我們也把oUserName作爲一個字符值來使用。
作爲一個完整的調用應該是這樣的:oUserName=CStr(Request.Item("UserName"))

接下來我們看,Request對象是如何通過COM自動化技術來支持形如Request("UserName")的調用的。

通過查看類型庫,知道Request對象派生自接口IRequest,IRequest提供如下只讀屬性的申明。

[id(00000000), propget]
HRESULT Item(
                [in] BSTR bstrVar,
                [out, retval] IDispatch** ppObjReturn);

只讀屬性Item的DISPID爲0,說明它是一個缺省屬性,通過腳本調用時,不必顯式寫出。該屬性的傳入參數是一個字符串,傳出值是一個IDispatch*接口指針。原來,上面得到的oUserName其實是一個IDispatch接口,並不是字符串值,只是在後面的調用中會自動實現IDispatch接口到字符串的轉換,從而在表面上我們可以直接把它作爲一個字符串來看待。

下面的問題是,IDispatch接口怎麼就會自動轉換。在自動化編程中,對於各種自動化類型之間的轉換主要通過VariantChangeTypeVariantChangeTypeEx進行。

下面是函數VariantChangeTypeEx的聲明
HRESULT VariantChangeTypeEx(
  VARIANTARG * pvargDest, 
  VARIANTARG * pvarSrc, 
  LCID  lcid,            
  unsigned short wFlags, 
  VARTYPE vt             
);

MSDN中對函數有這麼一段解釋。
An object is coerced to a value by invoking the object's Value property (DISPID_VALUE).
翻譯過來是,通過調用對象的Value屬性(屬性ID爲DISPID_VALUE),將此對象強制轉換爲一個值。
其中DISPID_VALUE就是0,VariantChangeType在進行轉換時,如果發現pvarSrc是一個IDispatch接口,就會自動調用DISPID爲0的屬性方法,從而由這個屬性方法來具體實現IDispatch接口到其他值的轉換。

IDispatch接口具體轉換成什麼類型的值,由DISPID爲0的屬性方法決定。

下面我們寫一個簡單的實例:

定義一個對象CTest,實現接口ITest,ITest又派生自IDispatch;ITest定義一個屬性Item

第一步:先生成接口ITest及對象CTest

interface ITest: IDispatch {
        [id(00000000), propget]
        HRESULT Item(
                        [out, retval] VARIANT* pVariantReturn);
          };

class ATL_NO_VTABLE CTest :
 public CComObjectRootEx,
 public CComCoClass,
 public IDispatchImpl
{
public:

      ........................

 public:

 // ITest Methods
public:

 STDMETHOD(get_Item)(VARIANT * pVariantReturn)
 {
       CComVariant pvResult=L"This is a test";
       pvResult.Detach(pVariantReturn);
       return S_OK;
 }

第二步:

在其他要實現的對象中
STDMETHOD(get_Item)(BSTR bstrVar, LPDISPATCH * ppObjReturn)

      CComObject *pTest;
      CComObject::CreateInstance(&pTest);
     
      return pTest->QueryInterface(IID_IDispatch,(void**)ppObjReturn);
     


 

發佈了17 篇原創文章 · 獲贊 2 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章