VC语言

本类阅读TOP10

·VC++ 学习笔记(二)
·用Visual C++打造IE浏览器(1)
·每个开发人员现在应该下载的十种必备工具
·教你用VC6做QQ对对碰外挂程序
·Netmsg 局域网聊天程序
·Windows消息大全
·VC++下使用ADO编写数据库程序
·VC++学习笔记(四)
·非法探取密码的原理及其防范
·怎样在VC++中访问、修改注册表

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
今天发现VC7.1 中的一个大BUG

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

       昨晚在写一段OLE自动化代码时,遇到一个莫名其妙的错误:当我的程序调用使用了VARIANT类型参数的自动化接口时出现严重错误,一晚上没有查出来。晚上回家仔细想了想,今早一来几下就解决了,原来是VC的一个BUG。说是BUG,可能也不是它的BUG。闲话少说,我们进入正题。

       如果你需要重现这种错误,那很简单:在VC7.1中新建一个MFC单文档程序,选择支持自动化,并使用CHtmlView。新工程建立后,向导自动为我们的View建立了自动化接口,我们只需要向这个接口添加一个使用了VARIANT参数的方法就行了(在Class View窗口中选中接口,右键,然后选择Add\Add Method...)。如:

  [id(1), helpstring("上传一个文件到服务器,并返回相应文件在服务器中的整数标识")] VARIANT_BOOL UploadFile(BSTR file, BSTR comment, VARIANT fileId);

  在接下来,我们写一个HTML页面用于调用这个接口:
<HTML>
  <HEAD>
  </HEAD>
  <script language='jscript'>
  function Upload()
  {
   window.external.UploadFile('345', 'asd', 234);
   alert ('ok');
  }
  </script>
  <BODY>
  <Button onclick='Upload()'>试一下</Button>

  </BODY>
</HTML>

接下来修改你的View的实现,在其OnInitialUpdate()中加入

 Navigate2(_T("file://html file path/html file name "),NULL,NULL);

现在编译并执行这个程序,你会发现当你点了“试一下”按钮后,程序会提示在oledisp1.cpp的 690 行出错。仔细跟踪进去,你会发现出错原因是参数类型不配置造成的。
        可是看看向导为我们生成的代码:

// 接口映射
BEGIN_DISPATCH_MAP(CJILClientView, CHtmlView)
    DISP_FUNCTION_ID(CJILClientView, "UploadFile", dispidUploadFile, UploadFile, VT_BOOL, VTS_BSTR VTS_BSTR VTS_VARIANT)
END_DISPATCH_MAP()
 
// ... 省略其它代码
 
// 接口函数
VARIANT_BOOL CJILClientView::UploadFile(LPCTSTR file, LPCTSTR comment, VARIANT fileId)
{
       AFX_MANAGE_STATE(AfxGetAppModuleState());
      
      // TODO: ...
       return  VARIANT_TRUE;
}
     怎么样,好象一点错也没有吧,类型完全配置,那我们的问题到底是什么原因呢?其实仔细想一下就不难想出,JScript等语言都是传VARIANT变量的引用,而不是象C++那样传值。因此,我们应该将上面代码中接口映射处的 VTS_VARIANT 改为 VTS_PVARIANT,而函数中相应的参数改为引用类型的。 改完后的代码如下
// 接口映射
BEGIN_DISPATCH_MAP(CJILClientView, CHtmlView)
    DISP_FUNCTION_ID(CJILClientView, "UploadFile", dispidUploadFile, UploadFile, VT_BOOL, VTS_BSTR VTS_BSTR VTS_PVARIANT)
END_DISPATCH_MAP()
 
// 接口函数
VARIANT_BOOL CJILClientView::UploadFile(LPCTSTR file, LPCTSTR comment, VARIANT & fileId)
{
       AFX_MANAGE_STATE(AfxGetAppModuleState());
      
      // TODO: ...     
       return  VARIANT_TRUE;
}

       现在再编译执行我们的程序,怎么样,没有问题了吧。看来是微软的老兄们想当然地把所有类型都按ULONG等简单类型处理了。

       结论:VC7.1中MFC的OLE自动化向导有严重BUG。当然,我没有试过这样改了后,从VB等程序调用这个接口会不会正常工作。有兴趣的朋友们可以自己试一下啦。试完后别忘了告诉我结果啊。^_^




相关文章

相关软件