CoGetClassObject在ATL项目中提供了许多第一次机会异常。我应该担心吗?

时间:2010-05-28 21:25:32

标签: c++ visual-studio exception com atl

我编写了一个COM对象,后者又使用了第三方ActiveX控件。在我的COM对象的FinalConstruct()中,我使用以下代码实例化ActiveX控件:

  HRESULT hRes;
  LPCLASSFACTORY2 pClassFactory;
  hRes = CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
  bool bTest = SUCCEEDED(hRes);
  if (!bTest)
   return E_FAIL;
  if (SUCCEEDED(CoGetClassObject(__uuidof(SerialPortSniffer), CLSCTX_INPROC_SERVER, NULL,
   IID_IClassFactory2, (LPVOID *)(&pClassFactory))))
  {  ... more set up code

当我跨过该行时(SUCCEEDED(CoGetClassObject(__ uuidof(SerialPortSniffer),..., 我在输出窗口中输入了20多行:

  

0x0523f82e处的第一次机会异常   在SillyComDriver.exe中:0xC0000005:   访问违规写入位置   00000000

我也得到了这些话:

  

0x051e3f3d处的第一次机会异常   在SillyComDriver.exe中:0xC0000096:   特权指令。第一次机会   在0x100ab9e6的异常   SillyComDriver.exe:0xC000001D:   非法指令。

请注意,这些是第一次机会异常。程序按预期运行我可以访问第三方方法/属性。尽管如此,我还是想知道他们为什么会这样。也许我实例化ActiveX控件的方式(我想用它的方法/属性而不是它的GUI东西)是不正确的?除了我正在展示的代码,我还把行

#import "spsax.dll" no_namespace 
在stdafx.h中

这就是我的简单演示项目所需的所有代码。我注意到了这个问题,因为我(无意中)在我的“真实”项目中设置了“异常中断”选项并且它在这一行上打破了。一旦我删除它,它也有效。

如果你对此感兴趣,那么谢谢你,也许我可以问另一个小问题。在我的演示项目中,如果我右键单击SerialPortSniffer并“转到定义”,它会将我带到文件C:.... \ AppData \ Local \ Temp \ spsax.tlh。有人可以解释一下吗?最后,在我的“真实”项目中,右键单击SerialPortSniffer并转到dif definition会导致“未定义符号'SerialPortSniffer'”。但它似乎并没有影响该计划。有什么设置我搞砸了吗?

顺便说一句,我的所有代码都是用VS2008编写的。

谢谢, 戴夫

2 个答案:

答案 0 :(得分:1)

这些绝对是您在Windows程序中遇到过的最糟糕的硬件异常。绝对没有理由像串口嗅探器这样简单的东西永远抛出这样的异常,更不用说捕获它们并处理它们了。

尽管如此,确实如此,你无能为力。你只能希望并祈祷这一天不会在屁股上写下你。就个人而言,该组件很快就会在我的捶打堆上结束。

#import语句自动生成COM类型库中的代码。它生成带有声明的.tlh文件和带有COM方法包装器的.tli文件。 .tlh文件包含智能指针(xxxxPtr),以便实例化COM对象并轻松调用其方法。这就是“Goto Definition”将您带到该文件的原因。

答案 1 :(得分:0)

通常无需担心。

当抛出异常时,会通知调试器,并且根据调试器配置,它可能会停止应用程序或让应用程序恢复正常。这是一个“第一次机会”的例外。如果应用程序恢复,那么它可以捕获异常,并在特殊情况下执行必要的操作。

如果应用程序没有处理异常,它将成为“第二次机会”异常,并再次通知调试器。调试器通常配置为此时停止应用程序,以便您查看出现了什么问题。

因此,如果您获得了第一次机会异常并且之后没有收到第二次机会异常,则通常意味着没有任何错误,并且应用程序正在处理“优雅”事件中的异常。

(另见http://blogs.msdn.com/b/davidklinems/archive/2005/07/12/438061.aspx