Problem mit #ifndef und #define



  • Hallo,

    #ifndef __ERROR_HANDLING__
    #define __ERROR_HANDLING__
    
        #ifndef ERROR_FILE
            #define ERROR_FILE TEXT("log.txt")
        #endif
    
        void ErrorWriteFile(TCHAR *szErrorMsg, HWND hwnd);
        void ErrorPrintSave(int ErrorNr, HWND hParent, BOOL bEditbox, BOOL bWriteToLog);
    
    #endif
    

    so sieht mein Header aus
    Er speichert jetzt den Fehler in "log.txt"

    In meiner main.c

    #define ERROR_FILE TEXT("errorlog.txt")
    #include "ErrorHandling.h"
    

    Und noch den Aufruf von "ErrorWriteFile":

    hErrorFile = CreateFile(ERROR_FILE, GENERIC_WRITE, 0, NULL,OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    

    Und jetzt hab ich mir gedacht müsste es doch den Fehler in "errorlog.txt" schreiben!? Mach es aber nicht warum?

    Verstehe ich das etwas mit den defines falsch?
    Mfg Pingu



  • a: Wohin schreibt er es denn stattdessen?
    b: Wo steht denn dieser CreateFile()-Aufruf?

    Eventuell sollte ich dich noch darauf aufmerksam machen, daß die ErrorHandling.c und die Main.c getrennt voneinander übersetzt werden - und erstere bemerkt nichts von deinem Bonus-#define in der main.c.



  • hängt vll. von der reihenfolge des aufrufs der beiden anweisungen

    #define ERROR_FILE TEXT("errorlog.txt") 
    #include "ErrorHandling.h"
    

    ab?



  • Dank erst mal

    CStoll schrieb:

    a: Wohin schreibt er es denn stattdessen?
    b: Wo steht denn dieser CreateFile()-Aufruf?

    zu a: in "log.txt"
    zu b: in der ErrorPrintSave() Funktion

    Hmm.. ok und wie könnte ich das dann machen das ich nicht als Parameter die Datei angeben muss, eine Default Datei( "log.txt") hab und wenn ich will doch in eine andere Datei schreiben kann?

    Ich bin da durch die Funktion "ReplaceFile" der WinApi drauf gekommen, da man für z.B. diese Funktion WINVER >= 0x0500 definieren muss z.B.

    #define WINVER 0x0500
    #include <windows.h>
    

    (wenns anders rum steht kommt error: redefinition

    So ist es in windef.h definiert:

    #ifndef WINVER
    #define WINVER 0x0400
    /*
     * If you need Win32 API features newer the Win95 and WinNT then you must
     * define WINVER before including windows.h or any other method of including
     * the windef.h header.
     */
    #endif
    

    Jetzt hab ich gedacht das geht bei mir auch!?



  • Das mit der WINVER funktioniert aber auch nur, weil diese Definition im Header direkt benötigt wird. Bei dir ist die Situation ein wenig komplizierter:

    //errorHandling.h
    #ifndef __ERROR_HANDLING__
    #define __ERROR_HANDLING__
    
        #ifndef ERROR_FILE
            #define ERROR_FILE TEXT("log.txt")
        #endif
    
        void ErrorWriteFile(TCHAR *szErrorMsg, HWND hwnd);
        void ErrorPrintSave(int ErrorNr, HWND hParent, BOOL bEditbox, BOOL bWriteToLog);
    
    #endif
    
    //errorHandling.c
    #include "errorHandling.h"
    
    void ErrorWriteFile(TCHAR* szErrorMsg, HWND hwnd)
    {
      ...
    }
    
    ...
    

    Diese Datei wird unabhängig von deiner main.c übersetzt - und hier gibt es, wie man sieht, keine neue Definition des Makros "ERROR_FILE" - damit arbeitest du hier mit dem Defaultwert. Eine Möglichkeit wäre es, die Makro-Definition per Compiler-Schalter /D für alle übersetzten Dateien mitzuliefern. Alternativ (besonders wenn die Logging-Bibliothek bereits fertig compiliert auf ihren Einsatz wartet) müsstest du eine Funktion bereitstellen, um einen Dateinamen zu übergeben:

    //im Header
    void ErrorSetFilename(TCHAR* szName);
    
    //im Sourcefile
    static TCHAR ERROR_FILE[MAX_PATH] = TEXT("log.txt");
    
    void ErrorSetFilename(TCHAR* szName)
    {
      _tcscpy(ERROR_FILE,szName);
    }
    
    //in main.c
    #include "errorHandling.h"
    
    int main()
    {
      ErrorSetFilename("messagelog.txt");
    }
    


  • Vielen dank an dich CStoll.

    Mal schauen wie ich das jetz machen werde.

    Aber wieder einmal was dazu gelernt 👍

    Schönen Abend noch an alle Tschau



  • Hier noch eine Möglichkeit, die sehr ähnlich deiner ersten ist:

    Angenommen wir haben folgende Files:

    err.h :  hier steht die Fehlerbehandlung drinnen
    a.h   :  Headerfile zu a.c
    a.c   :  Hier wird die Fehlerroutine ErrorWrite aufgerufen
    main.c:  Auch hier wird diese Routine aufgerufen.
    

    err.h

    #ifndef ERR_HANDLING
    #define ERR_HANDLING
    
    #include <stdio.h>
    
    #ifndef ERROR_FILE
    #define ERROR_FILE "log.txt"
    #endif
    
    static void ErrorWrite(int ErrorNr) {
        printf("%s:   ErrorNr: %d\n", ERROR_FILE, ErrorNr);
    }
    
    #endif
    

    a.h

    #ifndef A_H
    #define A_H
    
    void func(void);
    
    #endif
    

    a.c

    #include "a.h"
    
    #define ERROR_FILE "a:"
    #include "err.h"
    
    void func(void) {
        ErrorWrite(2);
    }
    

    main.c

    #include "a.h"
    
    #define ERROR_FILE "main:"
    #include "err.h"
    
    int main(void) {
        func();
    
        ErrorWrite(3);
        return 0;
    }
    

    Kompiliert habe ich wie folgt:

    gcc -W -Wall -pedantic -c -o a.o a.c
    gcc -W -Wall -pedantic -o a a.o main.c
    

    Und das ist das Ergebnis:

    a::   ErrorNr: 2
    main::   ErrorNr: 3
    

    Wie du siehst, hat er unterschiedliche Strings (ERROR_FILE) genommen.

    Wichtig ist, dass die Funktion ErrorWrite im Headerfile definiert und
    als static deklariert ist.

    Gruß mcr

    EDIT:
    @CStoll: Ich weiß, dass ich die Definition von ErrorWrite ins Headerfile
    genommen habe, was nicht den Vorgaben entsprach. Aber ich fand das so
    ganz nett.


Log in to reply