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

C#调用IAMCameraControl.GetRange:如何获取HRESULT而非COMException?

关于C#中IAMCameraControl.GetRange抛出COMException而非返回HRESULT的问题

我在C#中使用IAMCameraControl.GetRange方法,该方法的官方文档仅说明会返回HRESULT错误值,未提及异常相关内容,但实际代码中却触发了COMException,其内部包含对应的HRESULT值。请问为何会抛出异常而非直接返回错误?该如何解决?

我的接口定义如下:

[ComVisible(true)]
[ComImport]
[Guid("C6E13370-30AC-11d0-A18C-00A0C9118956")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAMCameraControl
{
    int GetRange([In] CameraControlProperty property, [In][Out] ref int pMin, [In][Out] ref int pMax, [In][Out] ref int pSteppingDelta, [In][Out] ref int pDefault, [In][Out] ref int pCapsFlag);
    int Set([In] CameraControlProperty property, [In] int lValue, [In] int flags);
    int Get([In] CameraControlProperty property, [In][Out] ref int lValue, [In][Out] ref int flags);
}

原因分析

  • .NET COM互操作的默认行为:.NET在处理COM接口调用时,默认会将失败的HRESULT(值小于0的HRESULT)自动转换为COMException抛出。这是互操作层为贴合托管代码的异常处理范式设计的,避免开发者手动检查每个方法的返回值。
  • 接口定义未显式保留签名:你当前的接口方法虽然声明返回int(对应HRESULT),但由于接口标记了InterfaceType(ComInterfaceType.InterfaceIsIUnknown),.NET互操作层仍然会默认拦截失败的HRESULT并抛出异常,不会直接返回错误码。

解决方法

要让方法直接返回HRESULT而不抛出异常,需要在每个接口方法上添加[PreserveSig]特性。该特性会告诉.NET互操作层:不要将失败的HRESULT转换为异常,直接返回原始的HRESULT值,由开发者自行处理错误。

修改后的接口定义:

[ComVisible(true)]
[ComImport]
[Guid("C6E13370-30AC-11d0-A18C-00A0C9118956")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAMCameraControl
{
    [PreserveSig]
    int GetRange([In] CameraControlProperty property, [In][Out] ref int pMin, [In][Out] ref int pMax, [In][Out] ref int pSteppingDelta, [In][Out] ref int pDefault, [In][Out] ref int pCapsFlag);
    
    [PreserveSig]
    int Set([In] CameraControlProperty property, [In] int lValue, [In] int flags);
    
    [PreserveSig]
    int Get([In] CameraControlProperty property, [In][Out] ref int lValue, [In][Out] ref int flags);
}

之后调用方法时,可手动检查返回的HRESULT:

int hresult = cameraControl.GetRange(CameraControlProperty.Zoom, ref min, ref max, ref step, ref def, ref caps);
if (hresult < 0)
{
    // 根据HRESULT值处理具体错误,比如映射到对应的错误逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 04:35:27