关闭

Request对象内幕--如何通过IDispatch接口返回BSTR字符串

1295人阅读 评论(0) 收藏 举报

在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);
     


 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:56485次
    • 积分:868
    • 等级:
    • 排名:千里之外
    • 原创:17篇
    • 转载:6篇
    • 译文:1篇
    • 评论:109条