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


 

相关文章推荐

深入体验JavaWeb开发内幕——使用Request对象设置防盗链

使用Request对象设置页面的防盗链       所谓的防盗链就是当你以一个非正常渠道去访问某一个Web资源的时候,服务器会将你的请求忽略并且将你的当前请求变为按正常渠道访问时的请求并返回到相应的...

数据库连接池-连接的关闭内幕

们经常会遇到这样那样的连接未关闭的问题,连接没有及时关闭导致的直接后果就是内存泄漏直至down机。我们也都知道解决的方式,但是在解决了问题之后经常会思考为什么会这样呢?连接close()掉,然后在创建...
  • xorxos
  • xorxos
  • 2015年05月08日 12:57
  • 242

关于"VC技术内幕"-控件上绘图代码的解释

vc技术内幕,有一节关于在对话框上控件画图(6.8节)的代码:   void CMyDlg::OnPaint() {     CWnd   *pWnd   =   GetDlgItem(ID...

数据库连接池-连接的关闭内幕

我们经常会遇到这样那样的连接未关闭的问题,连接没有及时关闭导致的直接后果就是内存泄漏直至down机。我们也都知道解决的方式,但是在解决了问题之后经常会思考为什么会这样呢?连接close()掉,然后在创...

Java Web应用程序开发-深入体验Java Web开发内幕之初步

从今天起我将一边介绍XML介绍之Schema一边开始介绍JavaWeb应用程序开发的介绍。作为第一次介绍,肯定是从WEB站点的构建过程开始讲起的即:   用Tomcat构建WEB站点 相关知识:...

JSP内置对象之--request对象

一、乱码解决 void setCharacterEncoding(java.lang.String env) throws java.io...

【极客学院】-python学习笔记-3-单线程爬虫 (request安装遇到问题及解决,应用requests提取信息)

极客学院课程网址:http://www.jikexueyuan.com/course/821_2.html?ss=1 任务: 爬取极客学院官方网站的课程库,并保存 Request...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Request对象内幕--如何通过IDispatch接口返回BSTR字符串
举报原因:
原因补充:

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