You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从CComDispatchDriver InvokeN调用的方法中获取HRESULT?

如何通过晚绑定COM调用获取原始HRESULT?

我通过晚绑定调用不同COM服务器的方法,代码如下:

HRESULT hr = drv.InvokeN(dispid, params.data(), static_cast<int>(params.size()), &retVal);
if (!SUCCEEDED(hr)) {...}

当被调用方法返回自定义HRESULT时,InvokeN仅返回0x80020009(发生异常),无法直接获取到原始的HRESULT。

我已经尝试过两种方式,但都没能拿到原始HRESULT:

  • 部分服务器实现了IErrorInfo接口,能获取错误描述,但无法获取对应的HRESULT:
IErrorInfo* pErrorInfo = nullptr;
GetErrorInfo(0, &pErrorInfo);
if (pErrorInfo != nullptr) {
    BSTR description;
    if (SUCCEEDED(pErrorInfo->GetDescription(&description))) {
        // 处理错误描述
        SysFreeString(description);
    }
    pErrorInfo->Release();
}
  • 调用GetLastError(),但它始终返回0。

解决方案

要获取目标方法返回的原始HRESULT,推荐使用以下方式:

1. 直接调用IDispatch::Invoke方法

InvokeN是封装后的简化调用,会将目标方法的异常统一包装为0x80020009。而IDispatch::Invoke可以直接暴露原始错误信息:

DISPPARAMS dp = { params.data(), nullptr, static_cast<UINT>(params.size()), 0 };
EXCEPINFO excepInfo = { 0 };
UINT argErr = 0;
HRESULT hr = drv->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dp, &retVal, &excepInfo, &argErr);

if (FAILED(hr)) {
    // 若hr不是DISP_E_EXCEPTION,可能就是原始返回值
    if (hr == DISP_E_EXCEPTION) {
        // 部分服务器会将原始HRESULT的低16位存入excepInfo.wCode
        if (excepInfo.wCode != 0) {
            HRESULT originalHr = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, excepInfo.wCode);
            // 处理原始错误码
        }
    } else {
        // 直接使用hr作为原始错误码
    }
}

2. 从IErrorInfo扩展接口提取(依赖服务器实现)

少数COM服务器会将原始HRESULT存储在IErrorInfo的扩展属性中,你可以尝试查询服务器是否实现了ISupportErrorInfo或自定义错误接口,但这种方式不具备通用性,仅适用于特定服务器。


内容的提问来源于stack exchange,提问作者MiB_Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 10:05:04