如何从将触发脚本异常处理程序的C++引发异常

How to raise an exception from C++ that will trigger scripting exception handlers

本文关键字:C++ 异常 异常处理程序 脚本      更新时间:2023-10-16

我一直在网上找到这个答案的零碎部分,但不是一个清晰的解决方案。

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

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

我的困境是我无法弄清楚如何构建C++以跨 ABI 边界抛出一个不会使调用者崩溃的异常。

为脚本客户端编写代码时,必须使用名为自动化的 COM 子集。 这决定了:

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

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

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

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

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

你可以通过以下方式使客户端处理"异常"

  1. 像你说的那样设置 IErrorInfo
  2. 返回非 HRESULT HR != S_OK

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

IDL 允许更多,但脚本主机(VBS、JScript、VBA 等)等"动态"客户端不会在本地使用这些客户端,因此互操作性不会是最佳的。