今天发现VC7.1 中的一个大BUG

类别:VC语言 点击:0 评论:0 推荐:

       昨晚在写一段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等程序调用这个接口会不会正常工作。有兴趣的朋友们可以自己试一下啦。试完后别忘了告诉我结果啊。^_^

本文地址:http://com.8s8s.com/it/it727.htm