2011-06-06 2 views
4

Je travaille actuellement sur une mise à niveau vers un projet qui utilise COM/MFC/(qui sait combien d'autres technologies). Dans le cadre de la mise à niveau, nous essayons de déplacer autant de fonctionnalités que possible dans le code C# géré, mais malheureusement, certaines choses ne peuvent tout simplement pas bouger (pour des raisons que je n'aborderai pas). L'une de ces choses est une section de code qui abuse grossièrement de COM, et renvoie des pointeurs dans les HRESULT qui seront ensuite transtypés en divers autres objets implémentant l'interface COM. J'ai essayé le code suivant pour convertir un HRESULT en un pointeur que je peux alors obtenir une interface à partir de:Obtenir un objet COM pour lancer une exception sur n'importe quel résultat sauf S_OK (0) dans 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); 
     } 

.... mais, aucune exception COM est jeté, et je devine que c'est parce que le pointeur n'est pas une valeur négative, et par conséquent n'est techniquement pas une erreur COM. Y a-t-il un moyen de configurer COM sur l'objet pour lancer une exception COM sur quelque chose MAIS S_OK (0)?

+2

Pointeurs dans le HRESULT? Sensationnel. Douleur. –

+2

Oh mon dieu! Toi pauvre âme ... – dkackman

Répondre

5

Deux pensées:

  1. Trouvez et tuer (ou sévèrement mutiler) celui qui a mis en œuvre cette bibliothèque
  2. Mettre en oeuvre une enveloppe en gestion C++ que vous aurez besoin d'obtenir au HResult de l'appel de méthode directement et I ne peut pas penser à un moyen de le faire en utilisant interop.

EDIT

Une autre option consiste à déclarer les interfaces COM en C# de sorte que la signature de chaque méthode retourne un HRESULT et utilisations [out retval] pour des valeurs de retour. Cela vous permettra d'obtenir et d'examiner le HRESULT de tous les appels de méthode, pas seulement ceux qui lancent une exception COMException.

Par défaut, COM interop typeimport "corrige" les signatures de méthode de sorte que le retour HRESULT est supprimé du côté géré et que la couche interop émet des exceptions pour E_FAIL etc., en rejetant essentiellement S_OK, S_FALSE et similaire.

This article a quelques explications et la documentation attrayante PreserveSig a quelques détails supplémentaires.

Cela nécessitera probablement que vous déclariez toutes les interfaces COM manuellement au lieu d'utiliser tlbimp, mais vous pouvez obtenir tlbimp pour préserver la signature des méthodes COM. Cela vous permettrait de rester purement en C# mais à votre place, j'irais avec C++ géré car il est plus facile d'interagir avec COM de cette façon non standard à partir de là.

Questions connexes