初步说明:我还没有完全掌握整个“interop”事情...
在.NET中使用COM库时,所有的HRESULT
方法都被包装成了当返回代码不是SUCCEEDED时抛出异常的形式。
//ATL magic exluded
class C {
HRESULT foo(){ return E_FAIL; }
};
// usage code:
if( SUCCEEDED( c.foo() ) ) {
// success code
} else {
// failure code
}
这段代码的.NET对应版本如下:
try {
c.foo();
// success code
} catch ( Exception e ) {
// failure code
}
有没有一种方法可以直接在.NET中访问COM返回代码,从而无需使用异常处理?
[PreserveSig]
是用于说明是否要将 HRESULTS 转换为异常的属性。还应该注意到,通常情况下您希望使用异常。HRESULTS 的存在仅因为并非所有语言都以相同的方式处理异常,因此需要一种基于非异常的机制来报告异常。一旦进入自己的语言环境,HRESULT 应该(理想情况下)转换为您语言的本机异常机制。 - Ian Boyd[PreserveSig]
的唯一原因。有些 COM 接口为了好或坏使用 HRESULT 作为布尔值;这些函数可以返回 S_OK、S_FALSE 或错误值。如果你不使用[PreserveSig]
,就无法知道它是否返回了 S_OK 或 S_FALSE。这不仅适用于 S_FALSE,而且适用于任何非错误 HRESULT。幸运的是,这样做的 COM 类很少,但它们确实存在。 - SvenIProgressDialog.HasUserCancelled
方法,它甚至不返回HRESULT
(像接口的其他方法一样),而是返回一个BOOL
。(几乎可以肯定这是 Windows 95 中原始接口中的一个错误,现在为了兼容性而被冻结) - Ian Boyd