Makro, ähnlich wie TRACE, variable Anzahl an Parametern



  • hallo

    ich will ein Makro schreiben das sich (aus Benutzersicht) genauso wie das TRACE bei MFC verhält
    es muss in der lage sein eine variable anzahl an Parametern entgegen zu nehmen (wie TRACE)
    MYTRACE(PARAMTERLISTE)

    und diese in einen CString sTmp; sTmp.Format(PARAMETERLISTE);
    umzusetzen.
    Grund: ich will die Eingaben dieses Makros in einem Edit in meinem Dialogfeld anzeigen.

    Frage: wie kann ich ein Makro schreiben, das eine beliebige Anzahl an Parametern entgegennimmt, es muss diese nicht verarbeiten, sondern einfach die gesamte Parameterliste an eine Funktion übergeben.

    Teflon



  • Mein Tip : MirakleWIP 🙂

    .. nene ich geb mal ein gedanken hier rein.. wie wäre es mit ein Makro das auf eine Funktion verweist.. klingt zwar unrealistisch weil die Funktion beim präprozessieren 🙂 noch nicht da ist aber .. eigendlich kein plan.. ist MYTRACE wirklich ein Makro ?)



  • .. wozu ein Makro.. geht denn keine Funktion ?



  • prinzipiell geht schon einen Funktion, aber ich will halt nebenher noch rausfinden wie das
    TRACE-Makro bei MFC funktioniert

    und das kann eine variable anzahl an Parametern entgegennehmen (oder es ist zigmal definiert, für jede Anzahl an Parametern, was ich aber nciht glaube)

    Beweis, das das TRACE beliebige Anzahl an Parametern entgegen nehmen kann:
    Auszug aus afx.h

    // The following trace macros are provided for backward compatiblity
    //  (they also take a fixed number of parameters which provides
    //   some amount of extra error checking)
    #define TRACE0(sz)              TRACE(_T("%s"), _T(sz))
    #define TRACE1(sz, p1)          TRACE(_T(sz), p1)
    #define TRACE2(sz, p1, p2)      TRACE(_T(sz), p1, p2)
    #define TRACE3(sz, p1, p2, p3)  TRACE(_T(sz), p1, p2, p3)
    

    die Alten Makros für eine fixe Anzahl an Parametern werden alle durch das neue TRACE Makro definiert



  • Also hier ist mal ein kleines Beispiel, wie du es mit einer Funktion erledigen kannst:

    int average( int first, ... )
    {
    int count = 0, sum = 0, i = first;
    va_list marker;

    va_start( marker, first ); /* Initialize variable arguments. /
    for(count;count<first;count++)
    {
    sum += i;
    i = va_arg( marker, int);
    }
    va_end( marker ); /
    Reset variable arguments. */
    return sum;
    }

    Diese Funktion gibt dir die Summer der Argumente zurück. Wobei der Erste Paramter die Anzahl der Argumente(ohne sich) angibt.
    Den Parameter kannst du ja durch ein Argument des Typs char* ersetzen den du dann Parst und so die Anzhal der Argumente feststellst.



  • summe der argumente das kenn ich doch irgendwoher 😃
    hab ich doch heute schon irgendwo in ner doku gelesen

    wie gesagt mich interessieren die einzelnen argumente gar nicht, ich will das was dem makro übergeben worden ist an CString.Format(formatstring,arg1,...)
    weiterreichen
    und ich nehm mal an, das es ziehmlich schwierig sein dürfte wenn ich erst mal die argumente auseinander gerupft hab die dann wieder alle zusammen für den aufruf dieser funktion zu verwenden

    noch mal so als beispiel wie ich das schlussendlich haben will

    #define MEINPERSOELICHESTRACE(ARGUMENTE)\
    CString sTmp;\
    sTmp.Format(ARGUMENTE);\
    ((MyApp*)AfxGetApp())->PrintLnToPersonalDebugWindow(sTmp);
    

    und die Verwendung

    MEINPERSOELICHESTRACE("Fehler: var1!=Sollwert, var1=%d, sollwert=%d",var1,sollwert);
    

    und der Präprozessor soll daraus dann das bauen

    CString sTmp;
    sTmp.Format("Fehler: var1!=Sollwert, var1=%d, sollwert=%d",var1,sollwert);
    ((MyApp*)AfxGetApp())->PrintLnToPersonalDebugWindow(sTmp);
    

    ps mir is ne idee gekommen wie ichs realisieren kann

    #define TRACESTART CString sTmp; sTmp.Format(
    #define TRACEEND ); ((MyApp*)AfxGetApp())->PrintLnToPersonalDebugWindow(sTmp);
    
    und verwendung
    TRACESTART "blub %d",blubvar TRACEEND
    

    aber wie gesagt das TRACE makro macht das ja auch irgendwie

    [ Dieser Beitrag wurde am 12.02.2003 um 11:53 Uhr von Teflon editiert. ]



  • TRACE wird durch den Funktionsnamen ersetzt. (Das TRACE-Makro hat keine Parameter)

    Deine Funktion:

    OutputFormatDebugString(LPCTSTR format,...);
    
    #ifdef _DEBUG
    #define TRACEXXX ::OutputFormatDebugString
    #else
    #define TRACEXXX 1 ? (void)0 : ::OutputFormatDebugString
    #endif
    

    [ Dieser Beitrag wurde am 12.02.2003 um 12:15 Uhr von Nemesyzz editiert. ]



  • was haltet ihr hier von

    #ifndef NDEBUG 
        #include <sstream>
        #include <windows.h>
    #endif 
    
    #ifndef NDEBUG 
        #define STREAMTRACE(value)                          \
        {                                                   \
            std::ostringstream dbs;                         \
            dbs << __FILE__ << '(' << __LINE__ << "): ";    \
            (value);                                        \
            ::OutputDebugString( dbs.str().c_str() );       \
        }
    #else  
        #define STREAMTRACE(value)                                 
    #endif // #ifndef NDEBUG 
    
    int foo(int,int) { return 1; }
    
    int main()
    {
        STREAMTRACE( dbs << 10 << "bla" << ::GetLastError() << std::endl );
        STREAMTRACE(( dbs << foo( 10, 10 ) << std::endl )); 
        // die extra klammern müssen sein weil er
        // wegen den kommer denkt ich will den makro ein zweiten paramter geben
        return 0;
    }
    

    in msvc sind die meldung sogra doppleklickbar (man spring sofort in die zeile wo die meldung her kamm)


Anmelden zum Antworten