2010-03-21 10 views

Respuesta

7

Estoy bastante seguro de que hay una manera, pero probablemente sea una mala idea. ¿Cómo garantizaría que el tiempo de ejecución no ha llamado a alguna función CRT durante su procesamiento interno que ha afectado al errno?

Por la misma razón, tampoco debe llamar directamente al GetLastError. El DllImportAttribute proporciona una propiedad SetLastError, por lo que el tiempo de ejecución sabe capturar inmediatamente el último error y almacenarlo en un lugar que el código administrado pueda leer usando Marshal.GetLastWin32Error.

Creo que lo más robusto que podría hacer en este caso es crear una DLL de C que realice tanto el trabajo C real como la captura del errno. (Tenga en cuenta que simplemente escribir un contenedor alrededor de la captura errno todavía tendría las preocupaciones mencionadas anteriormente.)

+0

Sí, estoy de acuerdo con esto. Probablemente sería mejor configurar un contenedor C como una función objetivo que a su vez devolvería el valor de errno. – supercheetah

2

Sí, es posible - GetLastError hace exactamente eso. Sin embargo, como señaló binarycoder, no debe hacer esto directamente; en su lugar, establezca SetLastError en su DllImport para realizar esto y almacenarlo en caché automáticamente (y para evitar problemas de subprocesos múltiples o funciones invocadas en tiempo de ejecución que modifican el valor errno); luego, al invocar el P/Función invocada, verifique su estado de retorno, y si muestra una condición de error - tiro Win32Exception, que lee el valor del último error automáticamente. Sí, incluso en Mono en Linux.

2

La solución es usar SetLastError en DllImport. Esto hará que el tiempo de ejecución guarde el último error para que se pueda acceder desde Marshal.GetLastWin32Error.

Hay dos problemas con llamar directamente GetLastError:

  • El tiempo de ejecución podría hacerlo en algún momento después de la PInvoke regresa antes de que pueda conseguir el último error
  • hilos .NET múltiples pueden residir en el mismo nativa hilo. Esto puede dar como resultado que 2 subprocesos .NET que hacen PInvokes, bibliotecas nativas que no conocen nada mejor, sobrescriban el último error. Entonces, el hilo A en .NET obtiene el último error del hilo B (potencialmente).
+0

¿Puedes mostrar un ejemplo de la sintaxis para usar 'SetLastError' en' DllImport'? –