(nota preliminar: No estoy todavía completamente al día con todo el asunto 'interoperabilidad' ...)COM `HRESULT` se envuelve en una excepción en .NET
Cuando se utiliza una biblioteca COM desde dentro .NET, todos los métodos HRESULT
se envuelven en algo que se lanza cuando el código de retorno no se CONSIGUE EXITOSAMENTE.
//ATL magic exluded
class C {
HRESULT foo(){ return E_FAIL; }
};
// usage code:
if(SUCCEEDED(c.foo())) {
// success code
} else {
// failure code
}
La contraparte .NET de este código lee:
try {
c.foo();
// success code
} catch (Exception e) {
// failure code
}
¿Hay una manera de acceder al código de retorno COM directamente en .NET, por lo que no es necesario el manejo de excepciones?
solo quería señalar más claramente que '[PreserveSig]' es el atributo que se utiliza para decir si quiere que HRESULTS se convierta en excepciones o no. También debe tenerse en cuenta que generalmente * desea * usar excepciones. Los HRESULTS solo existen porque no todos los idiomas manejan las excepciones de la misma manera, por lo que necesitaban un mecanismo no basado en excepciones para informar excepciones. Una vez que esté dentro de su propio idioma, HRESULT debe (idealmente) convertirse al mecanismo de excepción nativo de su idioma. –
Esa no es la única razón por la que te gustaría usar '[PreserveSig]'. Hay algunas interfaces COM que, para mejor o peor, usan HRESULT como booleano; estas funciones pueden devolver S_OK, S_FALSE o un valor de error. Si no usa '[PreserveSig]', no hay manera de saber si devolvió S_OK o S_FALSE. Eso no es solo para S_FALSE, sino para cualquier HRESULT que no sea un error. Las clases COM que hacen esto son afortunadamente raras, pero existen. – Sven
También existe el muy extraño método 'IProgressDialog.HasUserCancelled' que ni siquiera devuelve un' HRESULT' (como el resto de los métodos de la interfaz), sino que devuelve un 'BOOL'. (Casi seguro es un error en la interfaz original en Windows 95, y ahora está congelado para compatibilidad) –