u16string in VC2012



  • Wie stellt man sich denn das nun state-of-the-art vor in Zukunft?

    Ich habe eine Library die intern die WinAPI aufrufen muss. Welchen STring-Typ verwenden?

    a) Am saubersten wäre wohl alles via UTF-8 zu erledigen (http://www.utf8everywhere.org/). Datentyp wäre dann const char* bzw. std::string deren semantischer Inhalt UTF-8 sein soll (kann man zumindest zur compile-time garantieren, dass normale String-Literale ala "Test" nicht übergeben werden können sondern nur UTF-8 Literale ala u8"Test"?)

    b) An die WinAPI kann ich aber weiterhin nur LPWSTR übergeben, dementsprechend müsste ich dann jeden String hin- und herkonvertieren. Es wäre also auch sinnvoll hier char16_t/u16string zu verwenden und nur .c_str() aufrzurufen (falls kompatibel, hier wird ja nun gesagt LPWSTR ist wchar_t, was ja nicht unbedingt char16_t ist?!)

    Gibt's da noch keinen MSDN-Eintrag was nun "best practice" ist?

    @IrgendeinName: Das Konvertieren möglich ist weiß ich schon, das klärt aber nicht dieses best practice-Problem.

    MfG SideWinder



  • DrakoXP schrieb:

    In der Theorie sollten unter Windows wchar_t und char16_t identisch sein.
    AFAIK ist wchar_t unter Windows UTF-16 kodiert...

    Laut Standard hat char16_t ein eigener Typ zu sein.

    MSVC 11 hat das leider noch nicht implementiert, und macht daher einfach typedef unsigned short char16_t;

    wchar_t ist aber ein eigener Typ.



  • Ich weiß, dass es im VC2012 derzeit noch übel aussieht, deswegen auch die Frage nach dem Workaround.

    Nun bin ich mir aber nicht einmal mehr sicher wie man sich das überhaupt in Zukunft vorstellt.

    MfG SideWinder



  • SideWinder schrieb:

    a) Am saubersten wäre wohl alles via UTF-8 zu erledigen (http://www.utf8everywhere.org/). Datentyp wäre dann const char* bzw. std::string deren semantischer Inhalt UTF-8 sein soll (kann man zumindest zur compile-time garantieren, dass normale String-Literale ala "Test" nicht übergeben werden können sondern nur UTF-8 Literale ala u8"Test"?)

    Ich sehe jetzt keine Möglichkeit UTF-8 Literale zu garantieren. Der Typ von normalen Literalen unterscheidet sich ja nicht, bloss die Kodierung...?

    b) An die WinAPI kann ich aber weiterhin nur LPWSTR übergeben, dementsprechend müsste ich dann jeden String hin- und herkonvertieren. Es wäre also auch sinnvoll hier char16_t/u16string zu verwenden und nur .c_str() aufrzurufen (falls kompatibel, hier wird ja nun gesagt LPWSTR ist wchar_t, was ja nicht unbedingt char16_t ist?!)

    Vom Speicherinhalt wäre es unter Windows kompatibel - wchar_t und char16_t sind unter Windows immer beide UTF-16LE.
    Wäre da nicht die Strict-Aliasing-Regel, wäre ein reinterpret_cast hier völlig problemlos.

    ----

    So lange das Programm nicht portierbar sein muss, verwende ich weiterhin einfach wchar_t/wstring . Das funktioniert unter Windows super, keine Strict-Aliasing Verletzung, alle sind glücklich.
    Bei Portierung auf andere Systeme wäre es natürlich furchtbar, wenn dann wchar_t auf einmal 32 Bit gross ist und auch keine API mehr wchar_t annimmt ist man königlich angeschissen.

    Wenn es protierbar sein soll, dann ist wohl eher die Variante a) angesagt.
    Wobei das in gewissen Situationen unter Windows wirklich lästig wird. Wobei ich mir auch nicht sicher bin. Ideal wäre wenn Windows zusätzlich zu den A und W Varianten noch U8 Varianten anbieten würde. Wird aber vermutlich eher noch die Hölle zufrieren als dass das passiert.

    Aber vielleicht findet sich irgendeine OSSler Truppe mit zuviel Zeit die U8 Wrapper als Library entwickelt...

    EDIT: nochmal konkret zu deiner Frage:

    SideWinder schrieb:

    Ist u16string mit LPWSTR aus der WinAPI voll kompatibel? Also ist:

    SomeWinAPIFunction(mystr.c_str() /* LPWSTR */);
    

    in Ordnung?

    Nö, compiliert nicht, da bei MSVC char16_t == unsigned short , und wchar_t != unsigned short , also auch char16_t != wchar_t .

    Wenn man davon ausgeht dass MSVC irgendwann mal nen "echten" char16_t supporten will, dann ist das auch sehr gut so.
    Wenn dein Code oben compilieren würde, dann würden jetzt viele Leute anfangen genau das zu machen, und der ganze Code würde dann nimmer compilieren wenn mal der echte char16_t -Support kommt.

    Andrerseits könnte MS jederzeit das SDK umschreiben, so dass man die WinAPI funktionen dann mit wchar_t und char16_t verwenden kann. An den DLLs selbst müsste sich nichts ändern.



  • Da es sich hier um eine reine Bibliothek für Windows handelt soll ich also schlichtweg weiterhin TCHAR verwenden und alle sind glücklich?

    Neue C++11-Features und schönes UTF-8 weiterhin nur ein Traum?

    MfG SideWinder



  • Also wenn es ne Lib ist, und noch dazu ne Windows Lib, dann würde ich auf keinen Fall UTF-8 nehmen. Weil das unter Windows einfach keiner erwartet. Oh wie würde ich fluchen wenn ich mit sowas arbeiten müsste.

    Was TCHAR angeht... das ist für mich so ne Sache. Ich persönlich hasse TCHAR. Wenn man es richtig macht, wenns denn unbedingt sein muss, OK. D.h. aber mindestens unterschiedliche Namen für die A und W Version (speziell wenn es DLLs sind, aber bitte auch für LIBs).
    Und die Lib sollte damit klarkommen wenn in einem Prozess beide Varianten gleichzeitig verwendet werden. (DLL A ist ANSI und mit der ANSI Version von LIBX gelinkt, DLL B ist UNICODE und mit der UNICODE Version von LIBX gelinkt, und beide werden in Prozess C geladen)

    Optimal finde ich Libs die einfach parallel char und wchar_t Overloads anbieten. Bei bestimmten Libs geht das auch super einfach, weil nur an ein paar wenigen Stellen Strings verwendet werden. Bei anderen wäre mir der Aufwand auch zu hoch.

    Und die letzte Variante wäre dann einfach nur wchar_t zu verwenden. Ich persönlich hätte damit überhaupt kein Problem. Gibt aber sicher genug Programmierer die das GANZ anders sehen 😉



  • hustbaer schrieb:

    Strict-Aliasing-Regel

    VS nutzt die nicht, wenn man sich da also eh festlegt..



  • cooky451 schrieb:

    hustbaer schrieb:

    Strict-Aliasing-Regel

    VS nutzt die nicht, wenn man sich da also eh festlegt..

    Richtig.

    Muss aber nicht immer so bleiben.
    (Wird vermutlich lange dauern, aber pfuh, vielleicht räumt MS ja irgendwann mal das SDK auf, und traut sich dann 5-10 Jahre später doch mal Strict-Aliasing zum Optimieren auszunutzen?)



  • Danke, werde nun schlichtweg bei TCHAR bleiben.

    MfG SideWinder



  • hustbaer schrieb:

    (Wird vermutlich lange dauern, aber pfuh, vielleicht räumt MS ja irgendwann mal das SDK auf, und traut sich dann 5-10 Jahre später doch mal Strict-Aliasing zum Optimieren auszunutzen?)

    Das glaubt doch niemand wirklich. Nicht in 20 Jahren. 😃



  • http://msdn.microsoft.com/en-us/library/cc230355(v=prot.10).aspx

    hier schreibt microsoft leider nur die halbe wahrheit.
    LPWSTR wurde schon immmer in erster instanz getypedeft nach (WCHAR*).
    erst in folgender distanz löst sich WCHAR dann entweder auf in "wchar_t" oder "unsigned short".

    die msdn dazu noch:
    http://msdn.microsoft.com/de-de/library/ff381407(v=VS.85).aspx

    mit "TCHAR*" und "TEXT()" bist du wohl weiterhin am besten bedient.
    oder noch besser gleich "WCHAR*" und *W().


Anmelden zum Antworten