Seite 1 von 1

WinAPI - Spaß mit der Codepage

Verfasst: 10.04.2012, 16:17
von Schrompf
Hallo Leute,

ich mal wieder. Hat jemand von Euch Erfahrungen mit den Ansi-WinAPI-Funktionen auf abgedrehten Sprachversionen? Die Standard-Codepage, in der SHGetFolderPath() und Konsorten ihre Pfade zurückgeben, ist ja anscheinend Latin1, auch CP1252 genannt. Die reicht für die meisten europäischen Sprachversionen ja aus, aber sicher nicht mehr für China, Japan oder arabische Staaten. Was also mache ich auf diesen Systemen, wenn der AppData-Pfad bunte Zeichen enthält?

Windows versteht nun leider kein UTF8. Ich müsste also konsequenterweise alles auf UTF16-Unicode umstellen und überall zwischen UTF16 und UTF8 konvertieren, was die ganze schöne Abwärtskompatibilität von UTF8 nachdrücklich ruiniert. Außerdem ist es ein Haufen Arbeit. Deckt vielleicht ein OpenSource-Filesystem wie z.b. Boost.Filesystem sowas ab?

Hintergrund: ich habe kürzlich auf die harte Tour gelernt, dass mein Spiel seine eigenen Dateien nicht mehr findet, wenn man es in einem Pfad mit Umlauten ablegt. Die Pfade, die ich von der WinAPI zurückbekomme, sind in den Ansi-Versionen Latin1. Und Latin1-Pfade werden auch von fopen() und Konsorten erwartet. Nur benutzt z.B. Boost.Locale irgendwas Anderes zum Öffnen seiner Sprach-Files und findet die prompt nicht, wenn man die Lib mit einem Latin1-Pfad einrichtet. Ich bau da jetzt erstmal eine plumpe Konvertierung an dieser einen Stelle ein und verlasse mich drauf, dass Windows auch im Chinesischen mit den Pfaden umgehen kann, die es mir zurückgibt, aber ein ungutes Gefühl bleibt zurück. Daher würde mich interessieren, ob und wie ihr damit bisher umgegangen seid.

Und ich frage mich gerade, wieviele Spiele da draußen noch damit umgehen könnten...

Re: WinAPI - Spaß mit der Codepage

Verfasst: 10.04.2012, 16:36
von BeRsErKeR
Naja du kannst ja die Widechar-Versionen wie SHGetFolderPathW (Text als UNICODE) usw nutzen. Die gibts eigentlich für alles was mit Dateinamen und Texten zu tun hat. Ansonsten bieten viele Libs, die mit UTF-8 hantieren in der Regel Konvertierungsfunktionen wie Latin1ToUTF8 oder UTF8FromLatin1 an. Mit boost kenn ich mich nicht aus, aber ich denke da wird das auch geben.

Vielleicht hilft die das weiter: http://stackoverflow.com/questions/7370 ... e-encoding

Re: WinAPI - Spaß mit der Codepage

Verfasst: 10.04.2012, 16:51
von Krishty

Re: WinAPI - Spaß mit der Codepage

Verfasst: 10.04.2012, 16:54
von Schrompf
Die Konvertierung ist kein Thema, das bringt die ICU bzw. boost::locale mit. Ich habe nur nichts davon, wenn ich gezielt SHGetFolderPathW() aufrufe, da ich mit dem so bekommenen UTF16 auch nur wieder die UTF16-Versionen von fopen() und Konsorten füttern kann. Und bevor ich alles auf _wfopen() umschreibe, kann ich es auch gleich auf boost::filesystem umschreiben. Ich würde das Umschreiben im Allgemeinen aber gern vermeiden, daher würde mich interessieren, wie weit mich die Ansi-Versionen der WinAPI tragen können.

@Krishty: Das ist klar. Ich benutze intern ja auch überall UTF8. Das nützt mir aber nichts, wenn ich mit Windows reden muss. [edit] Zur Klarheit: dann muss ich entweder nach UTF16 oder nach Latin1 konvertieren. Ohne Konvertierung geht's nicht. Und nach Latin1 konvertiert dann sicher niemand mehr, weil es viele Verluste gäbe. Trotzdem bleibt die Frage: was gibt z.B. SHGetFolderPathA() zurück, wenn ich chinesische Zeichen im Verzeichnisnamen habe?

Re: WinAPI - Spaß mit der Codepage

Verfasst: 10.04.2012, 17:07
von Krishty
Schrompf hat geschrieben:Trotzdem bleibt die Frage: was gibt z.B. SHGetFolderPathA() zurück, wenn ich chinesische Zeichen im Verzeichnisnamen habe?
Warum kannst du nicht SHGetFolderPathW() aufrufen, das dir einen UTF-16-String zurückgibt?

Re: WinAPI - Spaß mit der Codepage

Verfasst: 10.04.2012, 17:14
von Schrompf
Krishty hat geschrieben:
Schrompf hat geschrieben:Trotzdem bleibt die Frage: was gibt z.B. SHGetFolderPathA() zurück, wenn ich chinesische Zeichen im Verzeichnisnamen habe?
Warum kannst du nicht SHGetFolderPathW() aufrufen, das dir einen UTF-16-String zurückgibt?
a) Das ist keine Antwort
b)
Schrompf hat geschrieben:Ich habe nur nichts davon, wenn ich gezielt SHGetFolderPathW() aufrufe, da ich mit dem so bekommenen UTF16 auch nur wieder die UTF16-Versionen von fopen() und Konsorten füttern kann. Und bevor ich alles auf _wfopen() umschreibe, kann ich es auch gleich auf boost::filesystem umschreiben. Ich würde das Umschreiben im Allgemeinen aber gern vermeiden, daher würde mich interessieren, wie weit mich die Ansi-Versionen der WinAPI tragen können.
Übersetzung: ich kann schon die W-Variante aufrufen. Es ist nur mit zusätzlicher Arbeit verbunden, um durchs Programm zu ackern und alle File-Interaktionen auf Widechar umzubauen.

[edit] Die Ansi-Funktionen ersetzen alle nicht-Latin1-Zeichen durch Fragezeichen (0x3f). Demzufolge ist das Scheitern außerhalb der Ansi-Codepage garantiert. Hallo, Boost.FileSystem

Re: WinAPI - Spaß mit der Codepage

Verfasst: 10.04.2012, 17:23
von Krishty
Ups, da sind meine Augen direkt zum @ gesprungen :) Nehme die Frage zurück.

Höchstpersönliche Meinung: Ich bin dafür, alles umzuschreiben. Selbst, wenn du die Codepages mit einer schicken Schicht wegabstrahiert kriegst, bleibt die unnötige Komplexität nämlich erhalten – beim Programmieren wirst du sie vielleicht nicht mehr sehen, aber beim Debugging schon. Und Compiler und CPU werden sie sowieso nicht loswerden. Außerdem ist Zweigleisigkeit früher oder später immer das schwächste Glied.

Re: WinAPI - Spaß mit der Codepage

Verfasst: 10.04.2012, 17:26
von Schrompf
Zustimmung. Habe auch gerade meinen Beitrag nochmal editiert. Aber wenn ich eh alle Datei-Arbeiten umschreibe, kann ich auch was plattformunabhängiges anstreben.

Re: WinAPI - Spaß mit der Codepage

Verfasst: 11.04.2012, 12:52
von BeRsErKeR
Schrompf hat geschrieben:Aber wenn ich eh alle Datei-Arbeiten umschreibe, kann ich auch was plattformunabhängiges anstreben.
Die Frage ist warum du überhaupt noch mit den ANSI-Versionen gearbeitet hast. Sind das noch Altlasten aus einem älteren Projekt?

Meiner Meinung nach empfiehlt sich bei der Arbeit mit gängigen C-APIs eh eine wiederverwendbare Abstraktions-Lib, die dann Funktionen wie fopen & Co abstrahiert und ggf. auch schon Funktionalität für Encoding-Alternativen enthält. So müsstest du jetzt z.B. nur an sehr wenigen Stellen nochmal hinlangen oder aber auch gar nichts mehr tun. Da sich die WinAPI im Großen nicht mehr sehr umfangreich ändert, wird so eine Abstraktions-Lib auch recht lange ohne viel Aufwand nützlich bleiben.

So eine Lib kann man darüber hinaus auch verwenden um einheitliche Schnittstellen für spezifische plattformabhängige Basisfunktionen zu gewährleisten (z.B. POSIX und WINAPI). Man denke nur an das ganze Netzwerkgedöns.