Сведения о вопросе

CPdeveloper

13:37, 28th August, 2020

Теги

mfc   macros   trace    

Как включить макрос TRACE в режиме выпуска?

Просмотров: 436   Ответов: 5

Макрос TRACE может использоваться для вывода диагностических сообщений в отладчик при компиляции кода в режиме отладки . Мне нужны те же самые сообщения в режиме выпуска . Есть ли способ достичь этого?

(Пожалуйста, не тратьте свое время на обсуждение того, почему я не должен использовать TRACE в режиме выпуска :-)



  Сведения об ответе

qwerty101

06:07, 22nd August, 2020

На самом деле, макрос TRACE гораздо более гибкий, чем OutputDebugString. Он принимает строку формата стиля printf() и список параметров, тогда как OutputDebugString просто принимает одну строку. Чтобы реализовать полную функциональность TRACE в режиме выпуска, вам нужно сделать что-то вроде этого:

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

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

   OutputDebugString(buffer);
}


  Сведения об ответе

SSESION

14:25, 13th August, 2020

Несколько лет назад мне нужна была подобная функциональность, поэтому я собрал следующий код. Просто сохраните его в файл, например rtrace.h, включите его в конце вашего stdafx.h и добавьте _RTRACE в режим выпуска, который определяет препроцессор.

Может быть, кто-то найдет ему применение :-)

Джон

#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


  Сведения об ответе

PROGA

21:14, 1st August, 2020

TRACE - это просто макрос для OutputDebugString . Таким образом, вы можете легко создать свой собственный макрос TRACE (или назвать его как-то иначе), который будет вызывать OutputDebugString .


  Сведения об ответе

lool

22:20, 11th August, 2020

Это самый простой код, который я видел

#undef ATLTRACE
#undef ATLTRACE2

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

видеть http://alax.info/blog/1351


  Сведения об ответе

lats

03:40, 23rd August, 2020

В MFC, TRACE определяется как ATLTRACE. И в режиме выпуска, который определяется как:

#define ATLTRACE            __noop

Таким образом, используя out-the-box TRACE из MFC, вы фактически не сможете прочитать любой текст TRACE, потому что он даже не будет записан. Вместо этого вы можете написать свою собственную функцию TRACE, а затем переопределить макрос TRACE. Вы могли бы сделать что-то вроде этого:

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.
}


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться