2011-06-06 74 views
4

除了S_OK(0)的任何结果,我目前正在升级到广泛使用COM/MFC /项目的异常(谁知道有多少其他技术)。作为升级的一部分,我们试图将尽可能多的功能转移到托管的C#代码中,但不幸的是有些东西无法移动(因为我不会介入)。其中一件事就是严重滥用COM的一段代码,并返回HRESULT中的指针,这些指针随后会转换为各种其他COM接口实现对象。我试过下面的代码的HRESULT转换为指针,我可以再从得到的接口:得到一个COM对象扔在C#

 MyComInterfaceInCS myObj = null; 

     try 
     { 
      world.GetTD_MyComInterfaceInCS(); 
     } 
     catch (COMException comException) 
     { 
      int pointerValue = Marshal.GetHRForException(comException); 

      IntPtr myObjPointer = new IntPtr(pointerValue); 

      myObj = (MyComInterfaceInCS) Marshal.GetObjectForIUnknown(myObjPointer); 
     } 

.... ,没有COM异常被赶,而且我猜测它因为指针不是负值,因此在技术上不是COM错误。有什么办法可以在对象上配置COM来抛出COM异常,但是S_OK(0)?

+2

指针在HRESULT?哇。疼痛。 – 2011-06-06 23:59:43

+2

哦,我的。你可怜的灵魂...... – dkackman 2011-06-07 00:00:49

回答

5

两个想法:

  1. 找到并杀死(或严重致残) 谁实现了这个库
  2. 实现托管C++ 的包装,你将需要直接在 方法调用的HRESULT得到和I 想不到使用interop做 的方法。

EDIT

另一种选择是在C#申报COM接口,使得每个方法的签名返回的返回值的HRESULT和用途[出RETVAL]。这将使您能够获得并检查所有方法调用的HRESULT,而不仅仅是抛出COMException的那些调用。

默认情况下,COM互操作类型导入“修复”方法签名,使得HRESULT返回在托管端被移除,互操作层抛出E_FAIL等异常,实质上抛弃S_OK,S_FALSE等。

This article有一些解释,并且PreserveSig attriubte文档有一些附加的细节。

这可能需要您手动声明所有COM接口,而不是使用tlbimp,但您可能能够获得tlbimp以保留COM方法的签名。

这将可以让您足不出户纯粹是C#,但在你的鞋子我会去与托管C++,因为它只是更容易在这种非标准的方式与COM交互从那里。