【发布时间】: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)) .
我的代码如下所示,其中src 是Microsoft.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。