Unicode und CreateProcess


  • Mod

    Klar. Dieser Code kann nicht funktionieren, wenn Unicode eingestellt ist.

    Der folgende Code geht immer:

    CreateProcess(
    NULL, // Kein Modulname, Kommando-Zeile benutzen
    _T("calc.exe"),// Kommando-Zeile
    ...
    

    Grund: Egal auf CreateProcessA oder CreateProcessW verwendet wird. Immer wird die Zeichenkette durch den T-Makro korrekt interpretiert.

    Der folgende Code nur in Unicode

    CreateProcess(
    NULL, // Kein Modulname, Kommando-Zeile benutzen
    L"calc.exe",// Kommando-Zeile
    ...
    

    Aus CreateProcess wird CreateProcessW! Es wird also ein wchar_t (Unicode) String erwartet.

    Und hier muss MBCS oder nichts eingestellt sein.

    CreateProcess(
    NULL, // Kein Modulname, Kommando-Zeile benutzen
    "calc.exe",// Kommando-Zeile
    ...
    

    Aus CreateProcess wird CreateProcessA! Es wird also ein char String erwartet.



  • Hallo Martin!

    Dein Code geht mit Sicherheit *nicht* mit Unicode! Zumindest nicht ab VS2005!

    Du hast die Kleinigkeit vergessen, dass der zweite Parameter beschreibbar sein muss. Und ab VS2005 werden string-literale im read-only Bereich abgelegt. Somit erzeugt dies eine Access-Violation.

    Für eine Funktionierendes Beispeiel siehe Doku:
    http://msdn.microsoft.com/en-us/library/ms682425.aspx
    (ganz unten)

    Dein Beispiel funktioniert nur für ANSI, da intern beschreibbarer Speicher allokiert wird um den String nach Unicode umzuwandeln 😉


  • Mod

    😮 Peinlich. Sorry!

    Man schmeißt halt nicht alle Postings durch den Compiler...



  • Warum kann bei der Verwendung von Unicode beim Aufruf von CreateProcess der Parameter CmdLine nicht direkt vor Ort z.B. mit L“calc.exe“ angegeben werden?

    also ist diese Aussage falsch bzw irreführend?



  • ameise schrieb:

    Warum kann bei der Verwendung von Unicode beim Aufruf von CreateProcess der Parameter CmdLine nicht direkt vor Ort z.B. mit L“calc.exe“ angegeben werden?

    also ist diese Aussage falsch bzw irreführend?

    Was heisst hier falsch. Die Aussage ist richtig:

    Der 2. Parameter *muss* ein beschreibarer String sein! String-Literale sind *nicht* beschreibbar, deswegen geht es nicht.



  • was ist ein String-Literal? Irgendwie versteh ichs nicht!



  • Ich hoffe, ich darf mich hier einmal kurz mit einer eigenen Frage einschalten, das passt gerade so gut.
    Soweit ich weiß, benutzt Windows für seine Unicode-Darstellung UTF-16, stimmt das? Was ist denn in Windows mit Multi-Byte-Strings gemeint? Wäre nicht auch UTF-16 dem Wortverstädnis nach so etwas? Zu diesem Multi-Byte finde ich immer so wenig.
    Unter Windows ist folglich ein wchar_t auch ein "short"? Wie geht man denn mit wstrings am besten um, schließlich kann man ja in UTF-16 auch ein Zeichen aus mehreren Einzelzeichen zusammensetzen und hat somit dasselbe Problem wie mit UTF-8, aka durch Buchstaben zu iterieren ist gar nicht mal trivial.

    Sorry, falls ich hier den Thread störe 😞

    Viele Grüße,
    Michael



  • wanderameise schrieb:

    was ist ein String-Literal?

    "abc"



  • Decimad schrieb:

    Soweit ich weiß, benutzt Windows für seine Unicode-Darstellung UTF-16, stimmt das?

    Genauer gesagt UCS-2, da es damals (NT3.1) noch kein UTF-16 gab 😉
    Siehe auch: UCS-2 vs. UTF-16 (not quite Kramer vs. Kramer)
    http://blogs.msdn.com/michkap/archive/2005/05/11/416552.aspx

    Decimad schrieb:

    Was ist denn in Windows mit Multi-Byte-Strings gemeint?

    I.d.R. meint man damit alle "proprietären" Zeichensätze die aus 1-n Bytes pro Codepoint bestehen.

    Decimad schrieb:

    Wäre nicht auch UTF-16 dem Wortverstädnis nach so etwas? Zu diesem Multi-Byte finde ich immer so wenig.

    Wenn man es genau nimmt: Ja. Nur mit dem unterschied dass es hier kein *Mulit*-*Byte* ist sonder max ein *Zwei*-*Wort* 😉

    Decimad schrieb:

    Unter Windows ist folglich ein wchar_t auch ein "short"?

    naja... würde ich jetzt nicht so sagen... per default sind diese Typen ab VS2008 nicht mehr kompatibel 😉

    Decimad schrieb:

    Wie geht man denn mit wstrings am besten um

    Die Frage verstehe ich nicht ganz.... wstring *ist* UTF-16...

    Decimad schrieb:

    , schließlich kann man ja in UTF-16 auch ein Zeichen aus mehreren Einzelzeichen zusammensetzen

    WAS verstehst Du unter *Zeichen*? Du kannst auch in UTF-32 ein Zeichen (Glyph) aus hunderten von Codepoints zusammensetzen!!!
    Ein sehr schönes Beispiel findet sich hier:
    http://blogs.msdn.com/michkap/archive/2006/02/17/533929.aspx
    😉

    Decimad schrieb:

    und hat somit dasselbe Problem wie mit UTF-8, aka durch Buchstaben zu iterieren ist gar nicht mal trivial.

    Wie gesagt. Das _Problem_ hast Du mit allen Codepoints; unabhängig des Encodings!

    Siehe auch mein Artikel zu Unicode:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-161855.html



  • Vielen vielen Dank für die ausführliche Klärung! Ich hätte mich Ohrfeigen können, dass ich deinen Artikel dazu nicht vorher aufgetan habe, dabei bin ich selber oft jemand, der an andere Stellen verweist O.O Sorry dafür.

    Viele Grüße,
    Michael



  • Er. Hm.

    Die Frage verstehe ich nicht ganz.... wstring *ist* UTF-16...

    std::wstring ist std::basic_string<wchar_t>, und auf Windows Plattformen ist üblich dass wchar_t 16 Bit breit ist. Das war's aber auch schon. Wenn man möchte kann man auch UTF-7 in einem std::wstring speichern. Oder die Liste der ersten so-und-so-viel Primzahlen. Oder einfach irgendwas 🙂

    Es hat sich eingebürgert unter Windows UTF-16 Strings in std::wstring abzuspeichern, und wenn man wo einem std::wstring vor den Latz geknallt bekommt, von einem Programmteil oder einer Library die nicht dokumentiert was denn drinnen ist, dann tut man gut daran anzunehmen dass UTF-16 drinnen steht.

    naja... würde ich jetzt nicht so sagen... per default sind diese Typen ab VS2008 nicht mehr kompatibel

    Ab VS 2005 wenn ich mich richtig erinnere. VS 2003 .NET hatte default noch auf "wchar_t per typedef", VS 2005 hat default bereits auf "wchar_t = builtin type" 😉


Anmelden zum Antworten