J'écris un wrapper autour d'une API non gérée assez volumineuse. Presque chaque méthode importée renvoie un code d'erreur commun en cas d'échec. Pour l'instant, je fais ceci:Traitement uniforme des codes d'erreur dans une API non gérée
ErrorCode result = Api.Method();
if (result != ErrorCode.SUCCESS) {
throw Helper.ErrorToException(result);
}
Cela fonctionne très bien. Le problème est, j'ai tellement d'appels de méthode non gérés que cela devient extrêmement frustrant et répétitif. Donc, j'ai essayé de passer à ceci:
public static void ApiCall(Func<ErrorCode> apiMethod) {
ErrorCode result = apiMethod();
if (result != ErrorCode.SUCCESS) {
throw Helper.ErrorToException(result);
}
}
Ce qui me permet de réduire tous ces appels à une ligne:
Helper.ApiCall(() => Api.Method());
Il y a deux problèmes immédiats avec cela, cependant. Tout d'abord, si ma méthode non gérée utilise les paramètres out
, je dois d'abord initialiser les variables locales car l'appel de la méthode est en fait dans un délégué. Je voudrais pouvoir déclarer simplement une destination out
sans l'initialiser. Deuxièmement, si une exception est levée, je n'ai vraiment aucune idée d'où elle vient. Le débogueur saute dans la méthode ApiCall
et la trace de la pile affiche uniquement la méthode qui contient l'appel à ApiCall
plutôt que le délégué lui-même. Comme je peux avoir plusieurs appels d'API dans une seule méthode, cela rend le débogage difficile. J'ai alors pensé à utiliser PostSharp pour encapsuler tous les appels non gérés avec la vérification du code d'erreur, mais je ne suis pas sûr de savoir comment cela serait fait avec les méthodes extern
. Si cela finit par créer simplement une méthode wrapper pour chacun d'entre eux, alors j'aurais le même problème d'exception qu'avec la méthode ApiCall
, non? De plus, comment le débogueur sait-il comment afficher le site de l'exception levée dans mon code s'il n'existe que dans l'assemblage compilé?
Ensuite, j'ai essayé d'implémenter un marshaler personnalisé qui intercepterait la valeur de retour des appels API et vérifierait le code d'erreur là. Malheureusement, vous ne pouvez pas appliquer un marshaler personnalisé pour renvoyer des valeurs. Mais je pense que cela aurait été une solution vraiment propre si cela avait fonctionné.
[return:
MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ApiMethod))]
public static extern ErrorCode Method();
Maintenant, je suis complètement à court d'idées. Quelles sont les autres façons de gérer cela? Que se passe-t-il si vous ne vérifiez pas ErrorCode.SUCCESS
?
+1 Semble cool. Désolé, je n'ai pas de réponse pour vous, mais bonne chance! –