_T(x) => __T(x) => L ## x ?



  • Hi,

    hin und wieder muss ich doch einmal für Windows programmieren, und jedesmal bekomme ich Kopfschmerzen bei den ganzen merkwürdigen Typedefs und Makros 😉

    Wie dem auch sei, ich versuche gerade ein Makro zu entschlüsseln, das folgendermaßen aussieht:

    #define CHECKVAR(x) if(!x){\
    	LOG( Logging::nError, L"Error during GetProcAdress of %s", L#x );\
    	return FALSE;\
    }
    
    #define GETPROC(y,x) y = (##x) GetProcAddress(hLibrary,_T("CSP") _T(#x));CHECKVAR(y)
    

    Mir ist klar was die Makros machen sollen, aber nicht, wie GETPROC zwei _T Makros verwenden kann?
    Also habe ich erst einmal geschaut, was _T noch einmal macht und kam zu folgender Makro-Expansion:

    _T(x) => __T(x) => L ## x

    Nun meine Frage:
    Was heisst denn

    L ## x

    ?

    L kann ich nicht weiter auflösen (scheint ein Typ zu sein, nur nach dem Buchstaben "L" zu googlen ist nicht so hilfreich :-)). Wenn L also ein Typ ist, was macht denn dann ## ?

    Und wieso funktioniert das dann auch noch in GetProcAddress? Der zweite Parameter sollte doch ein Pointer auf einen String sein, aber hier werden zwei Pointer gesetzt, getrennt durch ein Leerzeichen?

    Der Code funktioniert, aber mein Gehirn ist noch nicht ganz kompatibel damit 😃
    Kann mir das jemand ein wenig erklären?



  • Hmm also ## ist wohl eine Token concatenation in Makros, das habe ich nun herausgefunden.

    D.h. das nachher im Code so in etwa

    L"ABC"L"XYZ"
    

    steht?

    Das macht für mich aber immer noch keinen Sinn (oder ist das falsch)?



  • Dein Codeleferant will wohl Funtionen einer Lib ansprechen in möglichst generischer Form, also etwa

    y=(LIBPROC)GetProcAddress(hLibrary,"CSPLIBPROC"));

    Durch _T wird die ganze Sache nur versucht, Unicode-sicher zu machen.

    Der ## Operator fügt 2 Makroargumente zusammen,
    der # Operator macht aus einem Makroargument eine Stringkonstante mittels Einschluss in ""

    Allerdings ist mir nicht ganz klar, warum dein Codelieferant dies nicht auch für CHECKVAR durchgezogen hat, also

    #define CHECKVAR(x) if(!x){\
    LOG( Logging::nError, _T("Error during GetProcAdress of %s"), _T(#x) );\
    return FALSE;\



  • Wenn Du mit UNICODE compilierst, funktioniert das sowieso nicht. GetProcAddress kann mit UNICODE-Strings nichts anfangen. Schau Dir bitte mal die Doku zum zweiten Parameter an:

    http://msdn.microsoft.com/en-us/library/ms683212%28VS.85%29.aspx

    Genau, da steht LPCSTR und nicht etwa LPCTSTR. 😉



  • TheGrudge schrieb:

    ... ich versuche gerade ein Makro zu entschlüsseln, das folgendermaßen aussieht: ...

    Es gibt noch eine Möglichkeit, die betroffene Datei mit dem C-Präprozessor zu verarbeiten und sich die Ausgabe anzuschauen, z.B. mit dem GNU cpp:

    cpp datei.c
    

    Du bekommst den Code so zu sehen, wie ihn der Compiler zu sehen bekommt...


Anmelden zum Antworten