【问题标题】:How to raise an exception from C++ that will trigger scripting exception handlers如何从 C++ 引发将触发脚本异常处理程序的异常
【发布时间】:2012-09-27 03:26:29
【问题描述】:

我一直在网上找到这个答案的点点滴滴,但没有一个清晰的解决方案。

这就是我想要做的。 1) 创建一个 ATL 简单对象。 2) 向该对象添加一个返回 BOOL 而不是 HRESULT 的方法。调用者想要真/假返回值。 3) 向将提供 e.description 和 e.number 数据的 jscript 或 vbscript 调用者抛出异常。

RE 2) 我发现我可以使用 STDMETHODIMP_(BOOL) 和 [local] 来允许返回 BOOL RE 3) 我发现我可以通过 SetErrorInfo() 传递 IErrorInfo 来填充错误对象

我的困境是我不知道如何构建 C++ 以跨 ABI 边界抛出一个不会导致调用者崩溃的异常。

【问题讨论】:

  • 我不相信你可以跨 ABI 边界抛出 C++ 异常。这怎么可能?
  • 感谢马克的输入。那么有没有办法在 C++ 的脚本中触发 catch 块?如果不是,您建议我应该怎么做才能实现最佳实施?我相信我看到有人说您可以通过 Invoke/InvokeEx 执行此操作,但我不确定如何实现代码。

标签: c++ exception com atl abi


【解决方案1】:

当您为脚本客户端编写代码时,您必须使用称为自动化的 COM 子集。这表明:

  • 所有接口都必须从 IDispatch 派生
  • 一个组件类应该只实现一个源接口
  • 所有方法都必须返回 HRESULT,只有 STDMETHODIMP 有效
  • 参数类型必须限制为自动化允许的子集。

这意味着不允许使用 BOOL,它必须是 VARIANT_BOOL。您可以通过在 IDL 中这样编写来声明一个返回布尔值的方法:

 [id(42)] HRESULT Foo([out,retval] VARIANT_BOOL* retval);

在您的代码中将 VARIANT_TRUE 或 VARIANT_FALSE 分配给 *retval。脚本语言使用自然语法,如var = Foo()

您通过返回失败 HRESULT 在脚本客户端中生成异常。

【讨论】:

  • 汉斯非常感谢您!我是COM的初学者。这很完美。
  • 我不得不说,这肯定是比我预期的更愉快的回应。向你致敬。
【解决方案2】:

您可以通过

让客户端处理“异常”
  1. 像你说的那样设置 IErrorInfo
  2. 返回非 HRESULT hr != S_OK

因此,您需要 IDispatch/Interop 兼容接口,这需要 HRESULT 返回类型 (AFAIR)。

IDL 允许更多功能,但像脚本主机(VBS、JScript、VBA 等)这样的“动态”客户端不会本地使用,因此互操作性不会是最佳的.

【讨论】:

  • 如果我返回 STDMETHODIMP_(BOOL) 作为返回类型,而不是 HRESULT,这会起作用吗?另外,这会自动调用脚本调用者 catch 块吗?还是只返回一个我必须在呼叫者端主动检查的号码?
  • 不,因为这不会返回 HRESULT。所以是的,你留下了老式手册 (C-style) 错误检查
  • 这正是它应该起作用的。错误的性质应在错误信息实例中描述,但实际的 COM 方法应返回失败位点亮 (0x80000000),这正是 sehe 所描述的。
  • 感谢 WhozCraig。那么我是否必须牺牲将 BOOL 返回给调用者才能使其正常工作的能力?或者我还能发回 TRUE FALSE 吗?调用者期待一个布尔值。
  • + 实现ISupportErrorInfo,表示IErrorInfo已经有效设置,需要查询。
猜你喜欢
  • 1970-01-01
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-25
相关资源
最近更新 更多