WinApi Unicode Problem Compilerfehler



  • Hallo.

    ich habe hier ein kleines Problem, mit Unicode. Folgendes Code-Beispiel will einfach nicht kompilieren (Benutze mingw).

    #ifdef _UNICODE
    #   ifndef UNICODE
    #       define UNICODE
    #   endif
    #endif
    
    #include <windows.h>
    
    int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
    {
        MessageBox(0, "Hello, Windows", "MinGW Test Program", MB_OK);
    
        return 0;
    }
    

    Und hier der Fehler.

    error: cannot convert 'const char*' to 'const WCHAR*' for argument '2' to 'int MessageBoxW(HWND__, const WCHAR, const WCHAR*, UINT)

    Ich habe nun herrausgefunden das ich Unicode definieren muss. Was ich ja auch machen, siehe Zeile 1-5. Nun meine Frage warum geht das immer noch nicht?

    Was jedoch funktioniert ist wenn ich Zeile 11 in das hier verwandle.

    MessageBox(0, L"Hello, Windows", L"MinGW Test Program", MB_OK);
    

    Jedoch will ich das so nicht schreiben... gibt es da noch eine andere Option?

    Der Umgang mit der Win32-Api scheint mir irgendwie unnötig kompliziert zu sein, wenn man nicht Visual Studio verwendet, aber mit dieser überladenen IDE komme ich überhaupt nicht klar. Darum verwende ich Qt-Creator mit mingw.

    Grüße.



  • Du kannst das TEXT-Makro aus der WinAPI nutzen:

    MessageBox(TEXT("Bla"), /*...*/); //TEXT erzeugt, abhaengig davon ob _UNICODE definiert ist oder nicht "Bla" oder L"Bla"
    MessageBox(_T("BlaBla"), /*...*/); //_T ist eine Kurzschreibweise von TEXT
    

    Wenn es dich stoert, irgendwas vor das Stringliteral setzen zu muessen oder es in Makros einzufassen kannst du leider nicht mit Unicode arbeiten - das ist aber kein Fehler des WinAPI. C++ musst du Wide-Character-Literale ja immer mit L"" schreiben.



  • Hallo.

    Danke für die Hilfe.
    Ich glaube jedoch das ich hier einen gewaltigen Denkfehler habe. Mein obiges Beispiel kompiliert Fehlerfrei, wenn ich unter Visual Studio Multi-Byte Charset einstelle. Multi-Byte beinhaltet ja UTF-8 und Co. was ja wiederum Unicode ist.

    Also hier mal die Frage wo ist der Unterschied zwischen Multi-Byte und Unicode? Ich dachte da gibt es keinen unterschied, denn Unicode hat ja die Angewohnheit für ein Zeichen statt ein Byte zwei zu verwenden, Beispiel wäre hier "u" und "ü", das ein und das selbe wäre wenn ich keine Multi-Byte Funktionen verwenden würde. Komme irgendwie nicht dahinter wo hier der Denkfehler liegt.

    Wenn Unicode definiert ist, was ich ja gemacht habe sollte doch ein char automatisch nach wchar konvertiert werden oder nicht? Ist das nicht der Sinn? Wenn ich jedesmal einen Prefix schreiben muss kann ich mir doch auch die Definition sparen und explizit die Unicode-Funktion verwenden. Außerdem macht es den Code ja nicht mehr kompatibel, oder sehe ich das falsch?

    Grüße.



  • create_problem schrieb:

    Wenn Unicode definiert ist, was ich ja gemacht habe sollte doch ein char automatisch nach wchar konvertiert werden oder nicht?

    Eben nicht. Multibyte oder Unicode einzustellen sorgt unter VS (und, wie ich mal staerkstens vermute auch bei MinGW) jediglich dafuer, das in der WinAPI das #define MessageBox auf MessageBoxA oder eben MessageBoxW gelenkt wird.
    char bleibt char , char* bleibt char* , wchar_t bleibt wchar_t und wchar_t* bleibt wchar_t* . Und ein ""-Literal bleibt eben auch ein ""-Literal; ein L""-Literal ein L""-Literal.Der Compiler aendert daran nichts, deswegen gibt es ja den Umweg ueber das Makro.

    Was deine Zeichensatz-Frage betrifft: Ich weiss nicht ob VS mit Multibyte UTF-8 meint, aber selbst wenn: Bei UTF-8 wird trotzdem eine Kette von normalen char s verwendet, bei exotischen Zeichen werden eben mehrere char s nacheinander Verwendet. Dagegen benutzt Unicode eine Kette von wchar_t s.



  • Multibyte ist ASCII und damit kein Unicode.
    wchar_t ist eine abgewandelte Variante von UTF16 soweit ich das gelesen habe. Unterstützung für UTF8 und UTF32 gibt es damit nicht, und wenn du noch Linux benutzt wird dir wahrscheinlich der Unterschied zwischen UTF16 und Microsofts UTF16 auf die Füße fallen.
    chars können nie automatisch nach wchar_t konvertiert werden. Es gibt aber Funktionen die das übersetzen können.
    Du kannst explizit die Unicode-Funktionen benutzen, musst aber trotzdem ein L vor die Strings schreiben.
    Du kannst auch die allgemeinen Funktionen benutzen und _T() benutzen, was noch mehr Tipparbeit ist, dafür kannst du zwischen Unicode und ASCII zur Compilezeit wechseln.



  • Hallo.

    Vielen dank für die ausführlichen Erklärungen, ich habe es jetzt verstanden. Ich muss hier aber an einem Punkt nochmals nachhaken. Multi-Byte = ASCII das macht Sinn, denn die Erklärungen beweisen es und auch der Verhalten im Code, jedoch ist Multi-Byte in Zusammenhang mit ASCII ein Wiederspruch. Ich behaupte jetzt einfach mal das ASCII nicht Multi-Byte ist. Denn bei ASCII sind alle Zeichen gleich groß und Multi-Byte bedeutet das an manchen Zeichen auch ein weiteres Byte angehängt wird (was für Unicode spricht und nicht für ASCII). Darum war ich auch anfangs so verwirrt. Ich habe noch nie gehört das ASCII Multi-Byte ist. Denn auch in anderen Sprachen werden Multi-Byte Funktionen verwendet um Unicode zu unterstützten. Und Wikipedia bestätigt meine Denkweise zusätzlich:
    http://de.wikipedia.org/wiki/Multibyte_Character_Set

    ASCII ist demnach Single-Byte. Ich will hier niemanden auf den Schlips treten, denn ich weiß es selber auch nicht besser, ich möchte es lediglich kapieren. Irgendjemand muss sich ja irren.

    PS: Ist Encoding nicht der letzte schei...benkleister.

    Grüße.



  • Stellt man in Visual Studio auf Multibyte-Zeichensatz wirds unbequem - Würde ich nicht freiwillig machen 😉

    Den von der CRT aktuell verwendeten Zeichensatz kann man z.B. via _getmbcp auslesen.
    Unter deutschem Windows wird man meistens "Codepage 1252" haben, was ein Single-Byte Zeichensatz ist, unter einem japanischen Windows mit Codepage 932 kann ein Zeichen aus 1 oder 2 Bytes bestehen.
    Wenn man unter Multibyte einfach "Ein oder mehr Bytes pro Zeichen" versteht, fallen da auch Single-Byte Zeichensätze mit rein 😉

    Edit: UTF-8 (Multibyte-Zeichensatz) ist unter Windows Codepage 65001 (CP_UTF8) 😉



  • Ach Mist, geeky war schneller.

    Aber hat vollkommen Recht. Geirrt hat sich hier niemand :). Ich habe mir mal was zu Multi-Byte Charset auf MSDN (http://msdn.microsoft.com/en-us/library/5z097dxa.aspx) durch gelesen (hätte ich auch früher darauf kommen können).

    Abschließend kann man sagen das Multi-Byte der letzte Murks ist, wenn dann Unicode. Multi-Byte bedeutet bei Visual Studio das Multi-Byte auch ASCII beinhaltet, aber fakt ist ASCII != Multi-Byte . Sprich es ist so ein Mix aus halb-Wahrheiten, jedoch nichts halbes und nichts ganzes. Hier ist die Namensgebung schlicht und ergreifend irreführend. Denn wie ich schon erklärt habe ist Multi-Byte NICHT ASCII. Unter Visual Studio wird ASCII aber zusätzlich unter Multi-Byte geführt.

    FAZIT: Wenn die Möglichkeit besteht, Finger weg von Multi-Byte und Unicode nehmen.

    Grüße.


Anmelden zum Antworten