Frage

Der TRACE-Makro kann verwendet werden, um beim Kompilieren des Codes Diagnosemeldungen an den Debugger auszugeben Debuggen Modus.Ich brauche die gleichen Nachrichten, während ich drin bin Freigeben Modus.Gibt es eine Möglichkeit, dies zu erreichen?

(Bitte nicht Verschwenden Sie Ihre Zeit damit, darüber zu diskutieren, warum ich TRACE nicht im Release-Modus verwenden sollte :-)

War es hilfreich?

Lösung

Tatsächlich ist das TRACE-Makro viel flexibler als OutputDebugString.Es benötigt eine Formatzeichenfolge und eine Parameterliste im printf()-Stil, wohingegen OutputDebugString nur eine einzelne Zeichenfolge benötigt.Um die volle TRACE-Funktionalität im Release-Modus zu implementieren, müssen Sie etwa Folgendes tun:

void trace(const char* format, ...)
{
   char buffer[1000];

   va_list argptr;
   va_start(argptr, format);
   wvsprintf(buffer, format, argptr);
   va_end(argptr);

   OutputDebugString(buffer);
}

Andere Tipps

Vor ein paar Jahren brauchte ich eine ähnliche Funktionalität, also habe ich den folgenden Code zusammengeschustert.Speichern Sie es einfach in einer Datei, z.B.rtrace.h, fügen Sie es am Ende Ihrer stdafx.h ein und fügen Sie _RTRACE zum vom Präprozessor definierten Freigabemodus hinzu.

Vielleicht findet jemand eine Verwendung dafür :-)

John

#pragma once

//------------------------------------------------------------------------------------------------
//
// Author:   John Cullen
// Date:     2006/04/12
// Based On: MSDN examples for variable argument lists and ATL implementation of TRACE.
//
// Description: Allows the use of TRACE statements in RELEASE builds, by overriding the
// TRACE macro definition and redefining in terms of the RTRACE class and overloaded
// operator (). Trace output is generated by calling OutputDebugString() directly.
//
//
// Usage:    Add to the end of stdafx.h and add _RTRACE to the preprocessor defines (typically
//           for RELEASE builds, although the flag will be ignored for DEBUG builds.
//
//------------------------------------------------------------------------------------------------

#ifdef _DEBUG

// NL defined as a shortcut for writing FTRACE(_T("\n")); for example, instead write FTRACE(NL);
#define NL _T("\n") 
#define LTRACE TRACE(_T("%s(%d): "), __FILE__, __LINE__); TRACE
#define FTRACE TRACE(_T("%s(%d): %s: "), __FILE__, __LINE__, __FUNCTION__); TRACE

#else   // _DEBUG

#ifdef _RTRACE
#undef TRACE
#define TRACE  RTRACE()
#define LTRACE RTRACE(__FILE__, __LINE__)
#define FTRACE RTRACE(__FILE__, __LINE__, __FUNCTION__)
#define NL _T("\n") 

class RTRACE
{
public:
    // default constructor, no params
    RTRACE(void) : m_pszFileName( NULL ), m_nLineNo( 0 ), m_pszFuncName( NULL ) {};

    // overloaded constructor, filename and lineno
    RTRACE(PCTSTR const pszFileName, int nLineNo) :
        m_pszFileName(pszFileName), m_nLineNo(nLineNo), m_pszFuncName(NULL) {};

    // overloaded constructor, filename, lineno, and function name
    RTRACE(PCTSTR const pszFileName, int nLineNo, PCTSTR const pszFuncName) :
        m_pszFileName(pszFileName), m_nLineNo(nLineNo), m_pszFuncName(pszFuncName) {};

    virtual ~RTRACE(void) {};

    // no arguments passed, e.g. RTRACE()()
    void operator()() const
    {
        // no arguments passed, just dump the file, line and function if requested
        OutputFileAndLine();
        OutputFunction();
    }

    // format string and parameters passed, e.g. RTRACE()(_T("%s\n"), someStringVar)
    void operator()(const PTCHAR pszFmt, ...) const
    {
        // dump the file, line and function if requested, followed by the TRACE arguments
        OutputFileAndLine();
        OutputFunction();

        // perform the standard TRACE output processing
        va_list ptr; va_start( ptr, pszFmt );
        INT len = _vsctprintf( pszFmt, ptr ) + 1;
        TCHAR* buffer = (PTCHAR) malloc( len * sizeof(TCHAR) );
        _vstprintf( buffer, pszFmt, ptr );
        OutputDebugString(buffer);
        free( buffer );
    }

private:
    // output the current file and line
    inline void OutputFileAndLine() const
    {
        if (m_pszFileName && _tcslen(m_pszFileName) > 0)
        {
            INT len = _sctprintf( _T("%s(%d): "), m_pszFileName, m_nLineNo ) + 1;
            PTCHAR buffer = (PTCHAR) malloc( len * sizeof(TCHAR) );
            _stprintf( buffer, _T("%s(%d): "), m_pszFileName, m_nLineNo );
            OutputDebugString( buffer );
            free( buffer );
        }
    }

    // output the current function name
    inline void OutputFunction() const
    {
        if (m_pszFuncName && _tcslen(m_pszFuncName) > 0)
        {
            INT len = _sctprintf( _T("%s: "), m_pszFuncName ) + 1;
            PTCHAR buffer = (PTCHAR) malloc( len * sizeof(TCHAR) );
            _stprintf( buffer, _T("%s: "), m_pszFuncName );
            OutputDebugString( buffer );
            free( buffer );
        }
    }

private:
    PCTSTR const m_pszFuncName;
    PCTSTR const m_pszFileName;
    const int m_nLineNo;
};

#endif // _RTRACE

#endif // NDEBUG

TRACE ist nur ein Makro für OutputDebugString.Sie können also ganz einfach Ihr eigenes TRACE-Makro erstellen (oder es anders nennen), das den Aufruf durchführt OutputDebugString.

Es ist ganz einfach Code, den ich gesehen habe

#undef ATLTRACE
#undef ATLTRACE2

#define ATLTRACE2 CAtlTrace(__FILE__, __LINE__, __FUNCTION__)
#define ATLTRACE ATLTRACE2

sehenhttp://alax.info/blog/1351

In MFC ist TRACE als ATLTRACE definiert.Und im Release-Modus ist das definiert als:

#define ATLTRACE            __noop

Wenn Sie also das standardmäßige TRACE von MFC verwenden, können Sie eigentlich keinen TRACE-Text lesen, da dieser nicht einmal ausgeschrieben wird.Sie könnten stattdessen Ihre eigene TRACE-Funktion schreiben und dann das TRACE-Makro neu definieren.Sie könnten so etwas tun:

void MyTrace(const CString& text)
{
  ::OutputDebugString(text); // Outputs to console, same as regular TRACE
  // TODO: Do whatever output you need here. Write to event log / write to text file / write to pipe etc.
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top