【问题标题】:Getting CLR object property raises Unable to cast COM object of type 'System.__ComObject'获取 CLR 对象属性引发无法转换类型为“System.__ComObject”的 COM 对象
【发布时间】:2019-03-15 22:22:15
【问题描述】:

我试图通过反射获取属性的值,但最终得到以下异常:

System.Reflection.TargetInvocationException: '调用目标抛出异常。'

内部异常: InvalidCastException:无法将“System.__ComObject”类型的 COM 对象转换为接口类型“Microsoft.Kinect.Interop.INuiColorCameraSettings”。此操作失败,因为 IID 为“{00A4B392-E315-470C-90B7-F7B4C3CE00C4}”的接口的 COM 组件上的 QueryInterface 调用因以下错误而失败:不支持此类接口(来自 HRESULT 的异常:0x80004002 (E_NOINTERFACE)) .

我的代码如下所示,其中srcMicrosoft.Kinect.ColorCameraSettings 的一个实例,propName = "Brightness"

var prop = src.GetType().GetProperty(propName);
if (prop != null)
{
    return prop.GetValue(src, null);
}

我也尝试了据称对 COM 更友好的方法,但遇到了同样的问题:

return src.GetType().InvokeMember(propName, System.Reflection.BindingFlags.GetProperty, null, src, null);

最有趣的是,没有任何迹象表明src 是一个 COM 对象: src.GetType().IsCOMObject 返回false

但从内部异常堆栈跟踪看来,src 对象在内部与 COM 对象交互。

   at System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget, Boolean& pfNeedsRelease)
   at Microsoft.Kinect.Interop.INuiColorCameraSettings.GetBrightness(Double& pBrightness)
   at Microsoft.Kinect.NuiColorCameraSettings.GetBrightness()
   at Microsoft.Kinect.ColorCameraSettings.get_Brightness()

如何在运行时通过反射获取该属性的值?

编辑:这是抛出异常时线程窗口的样子


编辑:一直想更新这个。这里的解决方案是在正确的线程上运行代码,在这种情况下,它是线程池中的一个工作线程。只需用Task.Run() 包裹电话就可以了。这个例外(至少对我来说)对根本原因不是很清楚。

【问题讨论】:

  • 我很确定 var 是在运行时绑定的。可能是您尝试通过反射获得的类型具有在运行时设置的内部属性?
  • 不,当您与 Kinect 交谈时,您可以放心地假设您使用的是 COM,它是 Microsoft 对其 C++ 代码的通用粘合剂。两个基本原因。 Kinect 产品很久以前就停产了,所以上帝知道你从哪里得到互操作库,并且它不兼容,就像例外所说的那样。或者此代码在工作线程上运行并且库不支持线程,请使用 Debug > Windows > Threads 来查看。请随意将 Kinect 设备带到停车场,并用您的汽车将其碾过几次,以另一种方式结束支持。
  • @HansPassant 感谢您的回复,让我对您最后的建议感到好笑。我在这里使用的是官方的 Microsoft Kinect SDK v1.8(顺便说一句,它仍然可用)。你是正确的,这里涉及到工作线程,但是当抛出异常时它在主线程上运行。你认为这段代码需要在名为“Background M-NUI Thread”的工作线程上运行??
  • 您可能必须在创建它的同一线程上使用该对象。那个线程应该是 STA。

标签: c# com kinect


【解决方案1】:

一直想更新这个。这里的解决方案是在正确的线程上运行代码,在这种情况下,它是线程池中的一个工作线程。简单地用 Task.Run() 包装调用效果很好。这个例外(至少对我来说)对根本原因不是很清楚。

【讨论】:

    【解决方案2】:

    我也在努力获取 System.__ComObject 的属性值。 最初,ComObject 是一个带有一些属性的 java 对象。 GetType() 解决方案对我不起作用,因此我进行了更多搜索,发现 TypeDescriptor 非常有用且舒适。

    根据您的设置,我认为是:

    if(TypeDescriptor.GetProperties(src).Find(propName, false) != null)
    {
       propval = TypeDescriptor.GetProperties(src).Find(propName, false).GetValue(src).ToString();
    }
    

    希望对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2016-02-02
      • 1970-01-01
      • 2018-06-05
      • 2018-06-20
      • 2018-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多