代码之家  ›  专栏  ›  技术社区  ›  rmeador

保护COM接口不受异常影响

  •  3
  • rmeador  · 技术社区  · 14 年前

    我通过COM接口公开了几十个对象,每个对象都有许多方法,总共有几百个方法。这些接口将我的应用程序中的业务对象公开给脚本引擎。

    我的任务是保护这些方法中的每一个不被抛出异常(用COM捕获并返回错误) Error() 函数,顺便说一下,我找不到任何相关文档,因为谷歌不可能做到这一点)。据我所知,这要求我在这些方法的每个方法的内部添加一个尝试/捕获。对于这数百种方法中的每一种,捕获块都将是相似或相同的,它们都有强烈的问题气味(严重违反了干燥原则),但我想不出任何方法可以避免更改每种方法。据我所知,这些方法是由COM直接调用的,没有中间代码,我可以钩住它们来捕获异常。我目前的最佳想法是为catch块制作一个宏,但它有自己的代码味道。有人能想出更好的办法吗?

    顺便说一句,我的应用程序的异常不是从std::exception派生出来的,所以如果有某种COM自动处理标准异常的方法,那就没有帮助了。遗憾的是,我无法将现有的异常更改为派生自std::exception。

    4 回复  |  直到 14 年前
        1
  •  3
  •   Community Anvaka    7 年前

    最可靠的C++方法是在这里使用宏。我准备接受投反对票,但是我们已经使用这个解决方案很多年了,到目前为止还没有看到任何严重的问题。

    定义用于清除的“begin method”宏 IErrorInfo try { 和“结束方法” } catch 以及错误处理。如果您正确地设计了宏,除了最必要的错误处理代码外,将所有代码都放在helper函数中,这将是一个可容忍的、可靠的解决方案,代码看起来整洁、可维护性适中。

    是的,那个 doesn't look good at all 但至少它是实现您想要的目标的可靠且符合标准的方法。

        2
  •  3
  •   Hans Passant    14 年前

    这里没有快乐的答案。允许C++或SEH异常终止COM方法是非法的。你 必须 捕获它们并将其转换为适当的hresult。coclass必须实现isupportserrorinfo和ierrorinfo接口,以便客户机能够获取异常信息。clr将很容易地这样做以生成定制的异常消息。

    您所说的error()方法很可能是ATL CComCoClass::Error() method . 它设置IErrorInfo将返回的异常信息。

    没有机制注入单个try/catch块来捕获所有可能的异常,直接从客户端调用COM方法。对于每个调用调用异常的C++代码的COM方法,您必须这样做。不愉快,但这应该在编写代码时完成。您可能需要包装它们中的每一个,因为现在很难确定它是否在调用可能抛出的代码。

    从技术上讲,您可以更改类工厂来创建一个包装器,它实现接口的每个方法并委托给实际方法。使用样板文件尝试/捕获处理程序。非常机械,你可能会想出一些宏来减少打击。

        3
  •  0
  •   Kyle Alons    14 年前

    Comet 是大大简化工作的一种方法。

        4
  •  0
  •   MSN    14 年前

    假设所有COM接口方法都使用 __stdcall 约定和假设您可以自己创建COM对象,您可以“简单地”创建一个包装COM对象,该对象通过 QueryInterface . 这个打包的COM接口应该是一个COM接口,其中每个vtable条目都被一个thunk替换,thunk用 try/catch .

    实际上,我并不建议这样做,但这是一种将运行时实现COM对象与外部系统隔离的方法。