In MFC C++ (Visual Studio 6) bin ich gewohnt, den TRACE-Makro zum Debuggen zu verwenden. Gibt es eine äquivalente Aussage für plain win32?Gibt es eine TRACE-Anweisung für Basic Win32 C++?
Antwort
_RPTn funktioniert gut, obwohl nicht ganz so bequem. Here is some code, die die MFC-TRACE-Anweisung als eine Funktion neu erstellt, die eine variable Anzahl von Argumenten zulässt. Fügt außerdem ein TraceEx-Makro hinzu, das die Quelldatei und die Zeilennummer voranstellt, sodass Sie auf den Speicherort der Anweisung zurückklicken können.
Update: Der ursprüngliche Code auf CodeGuru würde für mich im Release-Modus nicht kompilieren, also änderte ich die Art, wie TRACE-Anweisungen für den Release-Modus entfernt werden. Hier ist meine vollständige Quelle, die ich in Trace.h eingetragen habe. Dank Thomas Rizos für den ursprünglichen:
// TRACE macro for win32
#ifndef __TRACE_H__850CE873
#define __TRACE_H__850CE873
#include <crtdbg.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifdef _DEBUG
#define TRACEMAXSTRING 1024
char szBuffer[TRACEMAXSTRING];
inline void TRACE(const char* format,...)
{
va_list args;
va_start(args,format);
int nBuf;
nBuf = _vsnprintf(szBuffer,
TRACEMAXSTRING,
format,
args);
va_end(args);
_RPT0(_CRT_WARN,szBuffer);
}
#define TRACEF _snprintf(szBuffer,TRACEMAXSTRING,"%s(%d): ", \
&strrchr(__FILE__,'\\')[1],__LINE__); \
_RPT0(_CRT_WARN,szBuffer); \
TRACE
#else
// Remove for release mode
#define TRACE ((void)0)
#define TRACEF ((void)0)
#endif
#endif // __TRACE_H__850CE873
Schön, das ist ein nützlicher Ausschnitt. –
szBuffer sollte nicht global sein, wenn Sie TRACE in mehr als einem Thread verwenden – Anders
good point - Ich denke, wenn ich die Deklaration einfach in die TRACE-Funktion verschiebe, wird es den TRACEF-Makro allerdings brechen - ist das wahr? – jacobsee
aus der MSDN-Dokumentation, Macros for Reporting:
Sie die _RPTn verwenden können, und _RPTFn Makros in Crtdbg.h definiert, die Verwendung von printf-Anweisungen für die Fehlersuche zu ersetzen. Diese Makros verschwinden automatisch in Ihrem Release-Build, wenn _DEBUG nicht definiert ist. Sie müssen daher nicht in #ifdefs eingeschlossen werden.
Es wird auch Output. Dies wird jedoch beim Kompilieren der Veröffentlichung nicht entfernt.
Trace Makros, die Nachrichten mit Quellcode Link bieten, Laufzeitaufrufliste Informationen und Funktionsprototyp Informationen mit Parameterwerten:
fand ich, dass die Verwendung von _RPT()
Makro wird auch mit einer C-Quelldatei in Visual Studio 2005 arbeiten. Dieser Artikel Debugging with Visual Studio 2005/2008: Logging and Tracing bietet einen Überblick über TRACE, _RPT und andere Protokolltypen Makros.
erzeugen ich eine Linie für eine Protokolldatei der ASSRTLOG genannt, die Protokolle enthält und beim Schreiben des Protokolls in die Datei, kann ich auch die folgende Zeile im Quellcode:
_RPT1(_CRT_WARN, "ASSRTLOG: %s", szLog1);
Diese Linie stellt das gleiche Protokoll, das wird in die Protokolldatei in das Ausgabefenster von Visual Studio 2005 IDE eingefügt.
Möglicherweise interessieren Sie sich für die Vorgehensweise, die für die Protokollierung verwendet wird. Wir haben eine Funktion PifLogAbort()
, die eine Reihe von Argumenten akzeptiert, die dann verwendet werden, um ein Protokoll zu generieren. Zu diesen Argumenten gehört der Name der Datei, in der das Protokoll zusammen mit der Zeilennummer generiert wird.Das Makro sieht wie folgt aus:
#define NHPOS_ASSERT_TEXT(x, txt) if (!(x)) { PifLogAbort((UCHAR *) #x , (UCHAR *) __FILE__ , (UCHAR *) txt , __LINE__);}
und die Funktionsprototyp für PifLogAbort()
sieht wie folgt aus:
PifLogNoAbort(UCHAR *lpCondition, UCHAR *lpFilename, UCHAR *lpFunctionname, ULONG ulLineNo)
und das Makro zu verwenden, werden wir eine Zeile wie diese ein:
NHPOS_ASSERT_TEXT(sBRetCode >= 0, "CliEtkTimeIn(): EtkTimeIn() returned error");
Was dieser Makro tun wird, ist, dass, wenn der Rückgabecode kleiner als 0 ist (die Assertion fehlschlägt), ein Protokoll mit dem bereitgestellten Text generiert wird. Das Protokoll enthält die Bedingung, die das Protokoll zusammen mit dem Dateinamen und der Zeilennummer generiert hat.
Die Funktion PifLogAbort()
generiert Protokolle mit einer bestimmten Länge und behandelt die Ausgabedatei als Ringpuffer. Die Protokolle haben auch einen Zeit- und Datumsstempel.
In jenen Fällen, in denen wir den beschreibenden Text zur Laufzeit dynamisch erzeugt werden sollen, vielleicht den eigentlichen Fehlercodewert zur Verfügung zu stellen, verwenden wir die Funktion sprintf() mit einem Puffer wie im folgenden Codesequenz:
if (sErrorSave != STUB_BM_DOWN) {
char xBuff[128];
sprintf(xBuff, "CstSendBMasterFH: CstComReadStatus() - 0x%x, sError = %d", usCstComReadStatus, CliMsg.sError);
NHPOS_ASSERT_TEXT((sErrorSave == STUB_BM_DOWN), xBuff);
}
Wenn wir wollen, dass die Protokolle nicht generiert werden, müssen wir nur zu der einzelnen Header-Datei gehen, in der das Makro definiert ist, und es als nichts definieren und dann neu kompilieren. Wir haben jedoch festgestellt, dass diese Protokolle bei der Untersuchung von Feldproblemen sehr nützlich sein können und insbesondere bei Integrationstests nützlich sind.
ich nur so etwas wie diese verwenden (aus dem Gedächtnis, nicht getestet ...)
#define TRACE(msg) {\
std::ostringstream ss; \
ss << msg << "\n"; \
OutputDebugString(msg.str()); \
}
Und dann kann ich die Dinge schreiben wie: -
TRACE("MyClass::MyFunction returned " << value << " with data=" << some.data);
Sie, dass wickeln können in einige #ifdefs, um es in Release-Builds leicht zu entfernen.
Nur ein kleiner Fehler: 'OutputDebugString (ss.str(). C_str());' sollte anstelle von 'OutputDebugString (msg.str());' verwendet werden – Apokal
Windows Events sind ein möglicher Ersatz für TRACE
Makros, abhängig von Ihrem speziellen Szenario. Der Code wird in Debug- und Release-Konfigurationen kompiliert. Die Ereignisverfolgung kann dann dynamisch aktiviert und deaktiviert, in Echtzeit angezeigt oder auf dem Computer eines Kunden zur späteren Diagnose ausgegeben werden. Die Traces können auch mit Trace-Informationen korreliert werden, die von anderen Teilen des OS gesammelt werden.
Wenn Sie nur Informationen ausgeben müssen, wenn Code bestimmte Prüfpunkte erreicht, zusammen mit variablen Inhalten, Stack-Traces oder Anrufernamen, ist Visual Studio Tracepoints eine nicht-intrusive Option, dies zu tun.
- 1. Gibt es eine maximale Länge für einen HTTP BASIC Authentifizierungsbenutzernamen?
- 2. Warum gibt es die Basic EventArgs Klasse?
- 3. Win32: Gibt es eine Ersatz-GDI32.dll, die Hardwarebeschleunigung verwendet?
- 4. Gibt es eine Betriebssystem-API-Wrapper-Bibliothek für C++?
- 5. Gibt es einen Visual Basic 6-Decompiler?
- 6. Gibt es eine Option für lang-vb oder lang-basic für prettify.js von Google?
- 7. C++/CLI: Linker gibt "ungelöste Token" für win32 Funktion
- 8. Gibt es einen Modus für Visual Basic (VB6) in Emacs?
- 9. Hibernate Basic: Wie abzufragen, wenn es eine zusammengesetzte ID gibt
- 10. Gibt es Guava für C#?
- 11. Gibt es eine Entsprechung in C für C++ - Vorlagen?
- 12. Win32 LB_GETTEXT gibt Müll
- 13. Gibt es eine C++ Cross-Plattform „bezeichnetes Ereignis wie die "Create()" in Win32?
- 14. Gibt es ein Auto-Update-Framework für C++/Win32/MFC (wie Sparkle)?
- 15. Gibt es gängige Entwurfsmuster oder gängige Idiome, die für C++ win32 Multithreading-Programmierung wichtig sind?
- 16. win32 api für Process.BeginOutputReadLine
- 17. OpenThread() gibt NULL zurück Win32
- 18. Gibt es blank C++ 11 (oder Boost) Ersatz für InterlockedExchangePointer?
- 19. C/C++ Konsole Windows WIN32
- 20. Programmgesteuert erzeugen Sie eine C Win32 DLL
- 21. Gibt es eine Emacs-Enzyklopädie für Tastaturbelegungen?
- 22. Win32-Funktion für geplante Tasks in C++
- 23. C++ Win32 Konsole Farbe
- 24. Gibt es eine leichtgewichtige plattformübergreifende C++ - Dateisystembibliothek?
- 25. Gibt es eine funktionale Sprache für C++ - Ökosystem?
- 26. gibt es eine Warnung (Fehler), ähnlich wie C4061 für C#
- 27. Gibt es eine gute radixsort-Implementierung für Floats in C#
- 28. Gibt es ein AddRange Äquivalent für eine HashSet in C#
- 29. Gibt es eine Möglichkeit, Doxygen für C++ zu optimieren?
- 30. Gibt es eine gute Lösung für einen C# html Sanitizer?
Warum benutzt man heute noch Visual Studio 6? Die 2005 und jetzt 2008 waren lange frei. –