Comment envelopper les erreurs lors de l’appel de COM en C ++?

Pour suivre une procédure COM classique, chaque fois qu’une erreur survient, il faut effectuer les opérations suivantes:

  1. Vérifiez le HRESULT avec FAILED ou similaire, pour voir si une erreur est survenue.
  2. Créer une variable pour contenir un IErrorInfo (généralement CComPtr )
  3. Appel ::GetErrorInfo(0, &var) .
  4. Obtenez la version lisible de l’homme en appelant IErrorInfo::GetDescription .
  5. Convertissez le BSTR en un std::wssortingng .
  6. Convertissez le std::wssortingng en une forme de caractère char const* .
  7. Lancez un type d’exception défini par l’utilisateur qui dérive de std::exception qui expose les bits 1, 5 et 6 ci-dessus.

Tout cela semble beaucoup de passe-partout, qui doit contourner à peu près tous les appels de fonctions dans COM.

Je sais que le compilateur MSVC ++ fournit tout un tas de choses pour faciliter les tâches avec COM, comme ATL, et les extensions COM spécifiques au compilateur _com_error , _com_raise_error et similaires, mais je ne sais pas comment les utiliser, ou si elles sont même destiné à être utilisé par le code utilisateur.

Existe-t-il des stratégies typiques utilisées pour gérer cette complexité dans un environnement sûr et une condition de sécurité exceptionnelles?

La solution “évidente” est une ComException . Il peut gérer à peu près toutes les étapes – il suffit juste d’obtenir le HRESULT pour le ctor et de lancer l’object résultant (étapes 1 et 7).

Vous pouvez même écrire

 HRESULT check(HRESULT hr) { if(FAILED(hr)) throw ComException(hr); return hr; // Success comes in different forms. } 

prendre soin de l’étape 7 pour vous. Par exemple, check(pUnk->QueryInterface(MyID, &pMyIf));

Je crains qu’il n’y ait pas de moyen semi-standard qui vous soit fourni, même si vous regardez les exemples d’applications et l’utilisation de l’API sur msdn, ils montrent tous que vous devez faire manuellement toutes les vérifications HResult, vérifier si l’IPtr est valide etc. Vous devrez écrire votre propre fonction qui encapsule tout cela afin de ne pas dupliquer le code, cela ne devrait pas poser de problème.