Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Para mantenerse independiente del lenguaje de programación, el sistema COM de Windows y muchas API de Windows devuelven un tipo entero de 4 bytes llamado a HRESULT para indicar si una API se realizó correctamente o no, junto con cierta información sobre el error. Otros valores que deben pasarse al autor de la llamada se devuelven a través de parámetros de puntero que actúan como parámetros "out" y suelen ser el último parámetro de la signatura. Los lenguajes como C# y Visual Basic tradicionalmente traducen un código de error a una excepción para alinear con la forma en que se propagan los errores en el lenguaje, y esperan que las firmas de los métodos de interoperabilidad no incluyan HRESULT. Para traducir la signatura de método a una signatura nativa, el entorno de ejecución mueve el valor devuelto del método a un parámetro "out" adicional con un nivel más de direccionamiento indirecto (es decir, lo convierte en un puntero al tipo de valor devuelto de la signatura administrada) y asume un valor devuelto de HRESULT. Si el método administrado devuelve void, no se agrega ningún parámetro adicional y el valor devuelto se convierte en .HRESULT Por ejemplo, vea los dos métodos COM de C# siguientes que se traducen en la misma firma nativa:
int Add(int a, int b);
void Add(int a, int b, out int sum);
HRESULT Add(int a, int b, /* out */ int* sum);
PreserveSig en COM
Se espera que todos los métodos COM de C# usen la firma traducida de forma predeterminada. Para usar y exportar métodos sin la traducción de firmas ni la manipulación de valores HRESULT, agregue el PreserveSigAttribute a un método de interfaz COM. Cuando el atributo se aplica a un método, no se realiza ninguna traducción a la signatura y no se inician excepciones para los valores HRESULT con errores. Esto se aplica tanto a COM integrado como a COM generado por el origen. Por ejemplo, consulte la siguiente firma de método de C# con un PreserveSig atributo y su firma nativa correspondiente.
[PreserveSig]
int Add(int a, int b, out int sum);
HRESULT Add(int a, int b, int* sum);
Esto puede ser útil si el método puede devolver valores diferentes HRESULT que no son errores, pero debe controlarse de forma diferente. Por ejemplo, algunos métodos pueden devolver el valor S_FALSE cuando un método no produce un error, sino que solo devuelve resultados parciales y S_OK cuando devuelve todos los resultados.
PreserveSig con P/Invokes
El atributo DllImportAttribute también tiene el campo bool PreserveSig que funciona de forma similar a PreserveSigAttribute, pero cuyo valor predeterminado es true. Para indicar que el entorno de ejecución debe traducir la signatura administrada y administrar el valor HRESULT que se devuelve, establezca el campo PreserveSig en false para DllImportAttribute. Por ejemplo, vea las siguientes signaturas de dos invocaciones de plataforma (P/Invokes) en el mismo método nativo, una con PreserveSig establecido en false y la otra con el valor true predeterminado.
[DllImport("shlwapi.dll", EntryPoint = "SHAutoComplete", ExactSpelling = true, PreserveSig = false)]
public static extern void SHAutoComplete(IntPtr hwndEdit, SHAutoCompleteFlags dwFlags);
[DllImport("shlwapi.dll", EntryPoint = "SHAutoComplete", ExactSpelling = true)]
public static extern int SHAutoCompleteHRESULT(IntPtr hwndEdit, SHAutoCompleteFlags dwFlags);
Nota:
P/Invokes generados por el origen, que usan LibraryImportAttribute, no tienen campo PreserveSig. El código generado siempre supone que la firma nativa y administrada son idénticas. Para obtener más información, consulte Invocaciones de plataforma (P/Invokes) generadas por código fuente.
Controlar los valores HRESULT manualmente
Al llamar a un PreserveSig método que devuelve un HRESULT, puede usar el ThrowExceptionForHR método para iniciar la excepción correspondiente si HRESULT indica un error. De forma similar, al implementar un método PreserveSig, puede usar el método GetHRForException para devolver el HRESULT que indica un valor correspondiente para la excepción.
Serialización de elementos HRESULT como estructuras
Cuando se usa un PreserveSig método , int se espera que sea el tipo administrado para HRESULT. Sin embargo, el uso de una estructura personalizada de 4 bytes como tipo de valor devuelto permite definir métodos auxiliares y propiedades que pueden simplificar el trabajo con .HRESULT En la serialización integrada, esto funciona automáticamente. Para utilizar una estructura en lugar de int como representación administrada de HRESULT en el marshalling generado a partir del origen, agregue el atributo MarshalAsAttribute con Error como argumento. La presencia de este atributo reinterpreta los bits de HRESULT como estructura.