desarrolloMobile.NET Noticias

martes, febrero 07, 2006

Control de errores emitidos por las API de Windows en contextos P/Invoke

Durante una llamada a una API de Windows (sea Win32 o WinCE), mediante P/Invoke, suele ser muy probable que el código de error que devuelve la propia API no pueda ser recuperado, es decir que de alguna manera P/Invoke olvida ese valor. Además, llamadas del tipo GetLastError() pueden llevar a confusiones ya que desde que se genera el error en la primera llamada P/Invoke hasta la llamada de GetLastError(), el CLR puede haber llamado a otras APIs variando de esta manera el resultado de la esta última función.

Afortunadamente, el atributo SetLastError de DllImport asignado el valor true (el valor por defecto es false), permite ‘recordar’ a P/Invoke el resultado del error para el proceso en ejecución. La manera de obtener dicho resultado es utilizando el método GetLastWin32Error() de la clase Marshal (System.Runtime.InteropServices ), el cual devolverá el código de error emitido por la API de Windows. A partir de ahí lanzar una excepción con el código de error puede ser una opción.

Veamos un ejemplo en C# con la llamada a RasHangUp*

[DllImport(“coredll.dll”,SetLastError = true)] //si se utiliza en Win32 la llamada en a"rasapi32.dll"

public static extern uint RasHangUp(uint pRasConn);

if (RasHangUp (uiRas) != 0)

{

//si RasHangUp no devuelve 0, algo ha ido mal

int error = Marshal.GetLastWin32Error();

string msg = String.Format(“Error {0}”,error);

thrown new ApplicationException(msg);

}

* Para que no quede duda RasHangUp cierra una conexión RAS. La implementación en Win32 se hace llamando a rasapi32.dll y es:

DWORD RasHangUp(
HRASCONN
hrasconn
);

La implementacion en WinCE se hace llamando a coredll.dll y es:

DWORD RasHangUp(
HRASCONN Session
);

El parámetro de la declaración DllImport de RasHangUp puede pasarse también como IntPtr, int o uint, dependiendo del cáculo de referéncias.

No hay comentarios: