2010-11-17 17 views
7

Estoy escribiendo una biblioteca multiplataforma compartida (.so en Linux y .dll en Windows) usando C. Actualmente cuando hay un error, las funciones de la biblioteca devuelven el código de error adecuado y escriben información de error en el stderr. Las funciones de biblioteca también emiten información y depuran mensajes al stdout. Esto funciona bien para clientes basados ​​en consola.Estrategias de manejo de errores en una biblioteca compartida - C

Ahora esta biblioteca tendrá programas de cliente que usan la GUI programada usando C++ & wxWidgets. Me pregunto cuáles serían las mejores prácticas para manejar los errores y notificarlos. ¿Puede una aplicación de interfaz de usuario acceder a los datos que llegan a stdout y stderr en todas las plataformas?

Una manera alternativa en la que estaba pensando es en que la función de inicialización de la biblioteca inicializa una estructura que tendrá punteros de función. Todas las funciones de la biblioteca tomarán una instancia de esta estructura y llamarán los punteros a la función. De esta forma, el cliente puede elegir dónde imprimir los mensajes.

Me pregunto ¿cuál sería la forma obvia de resolver esto? Cualquier ayuda sería genial.

Respuesta

14

La práctica recomendada (en mi humilde opinión) es que una biblioteca no imprima nada en stderr (o stdout), ya que es posible que ni siquiera estén presentes. Además de la situación de la GUI, también tiene el caso de uso de una aplicación de servidor que no tiene una "consola", y puede querer registrar errores utilizando una función como syslog().

Algunos enfoques para el manejo de información de error sin imprimirlo directamente:

  • devolver un código de error numérico, y proporcionar una función para convertirlo en una cadena

  • devolver un código de error de estructura/objeto , que contiene información adicional

  • proporciona una función en un objeto "sesión" que devuelve información sobre el último error

  • permiten que la persona que llama para registrar una devolución de llamada que se invoca en el caso de un error

La única excepción a la regla de "no escribir en stderr de una biblioteca" que estoy razonablemente cómodo con es si una biblioteca tiene un parámetro de "modo de depuración" que habilita el registro de información detallada en stderr.

10

En general, no debe escribir en el stdout en absoluto desde su biblioteca, incluso en una aplicación de consola que podría dañar la salida que está produciendo la aplicación. stderr es un poco más perdonable, pero aún así no debería usar eso a menos que la aplicación lo solicite.

OpenSSL es una biblioteca compartida multiplataforma que tuvo el mismo problema para resolver. Su método tiene la biblioteca registra información de error detallada en una cola de error interna, que la aplicación puede solicitar cuando se ve un valor de retorno de error y luego presentar al usuario de la forma que sea apropiada. (También proporciona una función de conveniencia que vuelca toda la cola de errores a FILE *).

+0

una pregunta más. Entonces, en OpenSSL, ¿cómo se borra la cola de errores interna? –

+0

@Appu: hay una función provista para que la aplicación solicite el "próximo error". Esto elimina el error más antiguo de la cola interna y lo devuelve a la aplicación. – caf

1

En Linux, en lugar de imprimir el error en la salida estándar (o error estándar), debe registrar el error usando rsyslog. Como está tratando con GUI, quizás también pueda abrir un cuadro de mensaje (no siempre).

No tengo ni idea de las ventanas, pero creo que tiene algo similar.

2

Para los mensajes de registro, debe permitir que el cliente proporcione una función de devolución de llamada a la biblioteca para que el cliente pueda decidir qué hacer con ellos, p. enviar a syslog o mostrar en una ventana en la pantalla.

Para devolver errores, tiene tres estrategias básicas:

  1. un código de error y tienen una función que se traduce en un mensaje
  2. pasar un parámetro de puntero que apunta a un objeto que se llevará a cabo de error información del mensaje
  3. Tiene algún objeto de biblioteca global que contiene información de error de la última operación.

Haga lo que haga, no desea simplemente registrar el mensaje de error porque el cliente puede querer hacer algo con él. p.ej. presentar un cuadro de diálogo.

Probablemente vaya con 2 en su mayoría.

Cuestiones relacionadas