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

原创 2006年05月19日 10:29:00

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


 

16.MFC实现IDispatch自动化接口

本文演示了通用的不依赖类型库,自己查表实现IDispatch接口和借助MFC的分发映射表DISPATCH_MAP实现IDispatch接口的两种方法,提供了演示代码,据此可掌握不依赖类型库实现COM ...
  • wenzhou1219
  • wenzhou1219
  • 2016年07月30日 19:58
  • 1127

COM技术内幕(笔记)

COM——到底是什么?——COM标准的要点介绍,它被设计用来解决什么问题?基本元素的定义——COM术语以及这些术语的含义。使用和处理COM对象——如何创建、使用和销毁COM对象。基本接口——描述IUn...
  • cometwo
  • cometwo
  • 2015年04月25日 16:37
  • 2476

COM 组件设计与应用(十一)—— IDispatch 及双接口的调用

原文:http://www.vckbase.com/index.php/wv/1236 一、前言 前段时间,由于工作比较忙,没有能及时地写作。其间收到了很多网友的来信询...
  • jiftlixu
  • jiftlixu
  • 2016年03月10日 11:05
  • 864

VC中BSTR、Char*、CString类型相互转换

1、char*转换成CString 若将char*转换成CString,除了直接赋值外,还可使用CString::format进行。例如: char chArray[] = "This is ...
  • mitesi
  • mitesi
  • 2014年04月08日 16:16
  • 1493

在C++中如何将ActiveX控件所使用的BSTR数据转换成CHAR字符数组?

在C++中如何将ActiveX控件所使用的BSTR数据转换成CHAR字符数组?   BSTR类型是COM中使用的标准字符串类型。它其实是一个32位指针,保存字符串首字符的地址。        在C++...
  • luengyong
  • luengyong
  • 2013年12月11日 10:45
  • 985

20.ATL中实现可连接对象和接收器

可连接对象是COM中观察者模式实现,非常有用,特别和IE组件打交道时候要用到。本文使用ATL实现可连接对象和对应的接收器,提供完整代码实现,可对比学习。...
  • wenzhou1219
  • wenzhou1219
  • 2016年08月08日 09:35
  • 848

COM组件 IDispatch 及双接口的调用

一、前言 前段时间,由于工作比较忙,没有能及时地写作。其间收到了很多网友的来信询问和鼓励,在此一并表示感谢。咳......我也需要工作来养家糊口呀...... 上回书介绍了两种方法来写自动...
  • CNHK1225
  • CNHK1225
  • 2016年01月21日 15:41
  • 1672

Action中取得request,session的四种方式

Action中取得request,session的四种方式 在Struts2中,从Action中取得request,session的对象进行应用是开发中的必需步骤,那么如何从Action...
  • qq_31986157
  • qq_31986157
  • 2016年08月19日 15:05
  • 571

通过在拦截器配置request对象,在前台页面显示返回的消息(1)

通过在拦截器里添加request的Attribute属性,然后在前台分别使用struts2标签和request.getAttribute()方法接收,拦截器代码如下: /** * 用户登录认证拦截...
  • lutinghuan
  • lutinghuan
  • 2014年03月04日 18:42
  • 4425

关于jacob支持BSTR类型的经验总结

作者:朱金灿来源:http://blog.csdn.net/clever101           jacob是实现Java和COM之间互操作的一个开源中间件。网上大多的程序示例基本上是使用jacob...
  • clever101
  • clever101
  • 2015年03月30日 23:33
  • 1578
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Request对象内幕--如何通过IDispatch接口返回BSTR字符串
举报原因:
原因补充:

(最多只允许输入30个字)