2010-04-15 20 views
6

Estoy haciendo una biblioteca de C++ que va a ser P/invocada desde C#, por lo que no puedo romper/depurar el lado C++ de las cosas. Así que decidí agregar el registro para poder ver si algo sale mal y dónde sucede. Agrego un #define DebugMode 1 para determinar si debo iniciar sesión o no. Antes que nada no soy muy bueno en C++, pero sé lo suficiente como para moverme. Así que mis preguntas son:¿Hay una manera mejor que #if DebugMode para iniciar sesión

  1. ¿Hay una manera mejor que envolver #if DebugMode #endif s en cada registro de llamadas? Podría simplemente hacer eso dentro del método de registro y simplemente regresar si el registro no está habilitado, pero ¿no significará que todas esas cadenas de registro estarán en el ensamblado?

  2. Cómo puedo emular lo que hace con su printf "..." operador me permite pasar algo así como Log("Variable x is {0}", x);

  3. ¿Hay algún truco como obtener el número de línea o apilar información de algún tipo que trazar puedo usar en el registro?

Gracias!

+0

Esto no responde la pregunta directamente, pero * puede * depurar el código C++ que es P/invocado desde C#, solo en el cuadro de diálogo "adjuntar", asegúrese de tener marcado el "Código nativo" como una opción . –

+0

¿Dónde puedo encontrar esta opción? – Daniel

Respuesta

5

Una forma simple es simplemente definir una macro que no hace nada si no está en modo de depuración. De esta forma, no tiene que envolver todas las llamadas en un #ifdef.

una implementación simple podría ser:

#if DebugMode 
#define MY_LOG(string, ...) printf(string, __VA_ARGS__) 
#else 
#define MY_LOG(string, ...) 
#endif 

hay otras maneras y bibliotecas (como refuerzo) pero esto le dará algo de forma rápida.

+0

¿Contendrá esto todas las cadenas de depuración en el ensamblado? Con #if DebugMode Log ("algo") #endif, ¿las cadenas no se compilarían en el ensamblado si la depuración está deshabilitada? ¿Es esto lo mismo para su solución porque me gusta su apariencia? – Daniel

+0

Las cadenas serán eliminadas por el preprocesador si DebugMode se establece en 0. Simplemente diga 'MY_LOG (" Algo tenía un valor de% d ", algo);' y estás listo. Las cadenas solo estarán en el conjunto de depuración. –

+0

¡Excelente exactamente lo que quería! – Daniel

0

¿Qué pasa con la depuración de la biblioteca C++? En la biblioteca C++ Project Properties, Depuración, seleccione C# client en el campo Comando y comience a depurar.

Acerca del registro, ¿usted pregunta sobre el registro C++ o C#? Bot tiene constantes de preprocesador definidas solo en la configuración de depuración, puede usarlo.

+0

C++ logging. No puedo ver ningún cliente C# en ese campo, solo regsvr32 y la capacidad de Buscar – Daniel

+0

¿Conoces el nombre del ejecutable C# que llama a tu C++ Dll? Rellene este nombre de archivo en el campo Comando. Si no conoce el nombre del cliente, ¿cómo lo ejecuta? –

+0

Oh veo, no estaba seguro de lo que se suponía que debía poner ¡Gracias! – Daniel

2

Si la condición es un tiempo de compilación constante, por lo que su código (después de decodificación previa) se resuelve a algo como:

if (0) 
    do the logging 

A continuación, el compilador generalmente será lo suficientemente inteligente como para despojar el código muerto, incluyendo las cadenas que le pasaste (a menos que también hayas usado las cadenas en otro código que no fue eliminado, por supuesto).

Código que actúa como printf es bastante simple:

#include <stdarg.h> 

void log(char const &fmt, ...) { 
    if (do_logging) { 
     va_list args; 

     va_start(args, fmt); 
     vfprintf(output_file, fmt, args); 
    } 
} 

En una macro (es importante que sea en la macro, no la función llamada), puede utilizar __FILE__ y __LINE__ para el número de línea actual y nombre del archivo fuente para poner en el registro. Con el código anterior, probablemente (querrás) pasarlos antes de la cadena de formato.

+0

¡Muchas gracias! Ah ok, solo los pasaré como argumentos al método de registro – Daniel

2

Recomiendo usar Pantheios, y entonces nunca tendrá que preocuparse por DEPURAR /! DEBUG. La biblioteca utiliza plantillas C++ para asegurarse de que no se paga ningún costo de rendimiento cuando el registro no está habilitado. También es 100% seguro y extensible a los tipos definidos por el usuario.

bar_t bar; 

pantheios::log_DEBUG("foo ", bar, " was doing something you should remember"); 

Consulte su performance page para obtener más información.

+1

Lo verificaré, suena muy bien – Daniel

+0

Lo siento pero la misma página muestra claramente los costos de rendimiento cuando el registro no está habilitado. – Cookie

+0

¿Por qué lo siento? La página muestra los costos relativos cuando el registro está habilitado y cuando no está habilitado. En ambos casos, Pantheios tiene un rendimiento superior. (Recuerde que la escala de costos es logarítmica). – dcw

Cuestiones relacionadas