Unicodeunterstützung



  • Hallo Leute,

    ich habe die Aufgabe übertragen bekommen einen vorhandenen Quellcode Unicode"fähig" zu machen...

    Dazu hab ich zwei Fragen:

    1. Hat jemand einen netten Einstieg dazu? Was es alles zu beachten gilt? Wenn es ein wenig MFC-speziell ist, hätte ich nichts dagegen, obwohl ich es auch für Std-C++ brauche (C-Strings)
    2. Wie teste ich denn am Besten, dass meine Implementation auch richtig tut? Auf deutschen Systemen reichen ja normale chars, d.h. ich kann es mit normalen deutschen Wörtern schonmal nicht testen, oder?

    Frage 2 ist mir etwas wichtiger als 1.



  • Die MFC ist angeblich voll Unicode fähig. Da gibts im VC++ auch nen entsprechenden Präprozessor-Schalter.

    Auf deutschen Systemen reichen ja normale chars, d.h. ich kann es mit normalen deutschen Wörtern schonmal nicht testen, oder?

    Kommt drauf an, was du mit "reichen" meinst. Umlaute sind nicht mehr in der ASCII-Kodierung enthalten.
    Benutze halt irgendwelche japanischen Schriftzeichen. Auf Unicode.org kannst ihren Code ansehen, wie man die dann escaped, weiß ich jetzt aber nicht. In Java schreibt man im Quelltext \u0c32 und hat dann das Zeichen mit dem Code 0x0c32. Sowas geht in C++ Quelltext sicher auch, amsonsten musst halt ne Zahl in ein wchar_t casten.
    Beim Test musst du dann aufpassen, dass auch die verwendete Schriftart diese Zeichen kennt.
    Und siehe auch die Links in meiner Signatur...



  • Erstmal musst du die Datentypen und was je nachdem noch viel wichtiger sein kann, die Verarbeitung der Datentypen auf eine gewünschte Unicode Representation umstellen. Also beachte, dass UTF-8 oder UTF-16 nicht einfach in C Strings gepackt werden können, weil ein Zeichen nicht gleich einer bestimmten größe ist. Da brauchst du dann spezielle Strings, die damit umgehen können. Wenn du eine alte Software auf Unicode umrüsten musst, ist vermutlich UTF-8 das mittel deiner wahl, da hier Unicode auf 8 Bit Bytes gemapped wird.

    Dann musst du darauf achten, dass die Methoden zur Darstellung Unicode kompatibel sind und dann am besten direkt kompatibel zu der von dir genutzten Representation. Die MFC ist glaube ich für UTF-16 ausgelegt (oder doch nur für das veraltete UCS-2? Dann hättest du ein Problem und müsstelst einiges umbasteln).

    Also beachte:
    * Welche sekundär Librarys werden genutzt?
    * Wie wird der Text dargestellt (Fontrenderer, Konsole)

    ** Sind diese Komponenten Unicode kompatibel bzw. ist es ihnen egal?
    ja => Welche Unicode Representation erwarten die?
    nein => Kann man die Unicode kompatibel machen oder ersetzen?

    Ohne genaure angaben kann man aber nicht viel sagen.

    http://www.cl.cam.ac.uk/~mgk25/unicode.html
    http://www.unicode.org/



  • Du musst überall das TEXT() Makro benutzen.



  • Nein. Das muss er nur, wenn er sein Programm sowohl mit Unicode-Unterstützung als auch ohne compilieren will. Ich sehe dafür nicht wirklich einen Grund.



  • Sonst muss er halt L davor schreiben. Da kann man dann auch gleich ein paar Zeichen mehr schreiben und hat beide Möglichkeiten offen.



  • Hi,

    hab neulich ne Site von son Typen gefunden, der hat beschrieben wie man mit der STL unicode machen kann!

    http://83.246.114.104/patrick/schnippel.php?id=3

    Fand ich sehr interessant.



  • text schrieb:

    hab neulich ne Site von son Typen gefunden, der hat beschrieben wie man mit der STL unicode machen kann!

    Schön wie du über dich selbst sprichst. 👎 😡



  • Hallo,

    Danke schonmal für die Hinweise, die bringen mich schon ein Stück weiter, denke ich.
    Da die Frage aufkam, worum es eigentlich geht:
    Es ist im Grunde ein SDK, d.h. der Kunde, der das SDK verwendet bekommt eine Schnittstelle in Plain-C, so dass man die DLL/Lib/ActiveX auch mit anderen Sprachen verwenden kann. D.h. Strings werden eben (momentan noch, das muss ich ja ändern) per char* übergeben, Zahlen per int oder float. Also nur eingebaute Datentypen.
    Intern ist das SDK (größtenteils, wenn nicht sogar ganz) mit der MFC geschrieben (Klasse CString für Zeichenketten z.B.). Das SDK beinhaltet auch einige eingebaute Dialoge, auf denen in normalen Windowscontrols (Buttons, Statics, Editfelder u.ä.) eben Text steht und ausgegeben wird.

    Optimizer, wenn ich dich richtig verstanden habe, dann muss ich intern, wo die MFC für Strings verwendet wird, eigentlich nichts ändern, sondern nur die Linkereinstellung angeben. Richtig? Ich muss also nur die Schnittstelle ändern, so wie's aussieht.
    Würde mich nochmals über eine Antwort freuen, lese aber natürlich auch die Links noch durch.



  • Wenn du die MFC-eigene String-Klasse benutzt, kann ich mir nicht vorstellen, dass groß was schiefgeht.
    std::wstring ist nur bedingt brauchbar (random access is nicht).
    Der Gag ist ja, dass die MFC das WinAPI nur kapselt. Es gibt für fast jede API-Funktion ein Gegenstück für Unicode (MessageBoxA, MessageBoxW) und das Zeugs funktioniert auch. Welche aufgerufen wird, sollte vom Compilerschalter abhängen.
    Also ist wahrscheinlich wirklich nur die Schnittstelle zu ändern für den Kunden zu ändern.

    Das einzige was du grob falsch machen kannst ist IMHO, dass du irgendwelche Annahmen über die Größe eines Zeichens in Bytes machst oder sowat. Je mehr Highlevel du bleibst, desto weniger Probleme hast du.



  • du meinst statt sizeof einfach fix die Größe von beispielsweise 1 zu nehmen?
    Ich mach das normalerweise nie so, aber es schadet garantiert nicht, danach nochmals zu schauen. Danke für den Tip!
    Die Stringklasse der std verwende ich nicht, daher muss ich da ja nichts beachten.
    Ansonsten hab ich für heute Abend schonmal meinen Lesestoff und werde dann wohl morgen damit anfangen das umzubauen.



  • @dEUs
    Nein, was Optimizer meint ist, dass Windows UTF-16 nutzt. Also ein Multibyte Zeichensatz. Das bedeutet, dass du nicht davon ausgehen kannst, dass ein 2 Byte ein Zeichen sind.

    char in der API? Das wär für UTF-8 praktikabel, aber du willst doch UTF-16 nehmen?



  • std::wstring ist nur bedingt brauchbar (random access is nicht).

    Quatsch. Jeder Character hat doch ne feste Länge. Deswegen geht auch alles was mit std::string geht.



  • Oh Herr, lass Hirn auf ihn herunterfallen. Was haben kingruedi und ich ein paar Beiträge vorher gesagt?

    Bitte lesen. Danke.



  • versteh ich nicht



  • kingruedi schrieb:

    char in der API? Das wär für UTF-8 praktikabel, aber du willst doch UTF-16 nehmen?

    Diese Frage kann ich dir noch nicht beantworten. Bin erst grad eben heimgekommen und hab deswegen die Links noch nicht angeschaut.



  • Glaub ihm, du willst UTF-16 nehmen. 😃



  • Dann is ja gut 😉
    Hab mich mal sehr oberflächlich durch die Unicode-Seite gelesen (Hat mich ehrlich gesagt ein wenig erschlagen)
    Ein paar Fragen sind mir da schon wieder gekommen:
    Die Länge eines Zeichens scheint nicht festgelegt zu sein. Richtig? Woher weiss die Anzeigesoftware dann, wie lang ein Zeichen ist?
    Was ist (auch speziell auf die Kompilereinstellungen beim VisualStudio 7.1) der Unterschied zwischen Unicode-Zeichensatz und Multibyte-Zeichensatz?
    Bin dann mal weiterlesen ...



  • Die Länge eines Zeichens scheint nicht festgelegt zu sein. Richtig?

    Der Unicode Standard legt gar nichts über die Implementierung fest, er legt nur fest, welches Zeichen welchen Code hat.
    Wie dieser Code repräsentiert wird ist gleich.

    UTF-X sind Implementierungen des UCS. UTF-8 benutzt pro Zeichen mindestens 8 Bit, aber je nach Zeichen gerne auch 2 oder 3 oder 4 Bytes.
    UTF-16 benutzt entweder 2 oder 4 und UTF-32 immer 4. Du hast also nur bei UTF-32 anständigen random access auf ein Zeichen, weil bei den anderen Formaten, das n-te Zeichen nicht durch Pointerarithmetik bestimmt werden kann.

    Woher weiss die Anzeigesoftware dann, wie lang ein Zeichen ist?

    Hängt von der Kodierung ab. Bei UTF-8 z.B. wird das erstes Bit angeschaut. Ist es gesetzt (und nur dann), wird das zweite Bit angeschaut, usw.
    Dann werden [gesetzte Bits] - 1 Bytes genommen und daraus der Code erstellt, womit man dann ein Zeichen gelesen hat.
    UTF-16 ist ein bisschen einfacher, kann aber insgesamt sogar weniger Zeichen kodieren (ist aber nur theoretisch... der volle UCS ist implementiert).
    Solange du nur Text ausgibst, muss dein String eh sequentiell gelesen werden und du hast kein allzu großes Problem. Nur Random Access ist halt fast nicht möglich.

    MB von Microsoft funktioniert vom Prinzip her ein bisschen wie UTF-8 ist aber probrietär, benutze es nicht. MS selber ist davon auch schon weggekommen.

    P.S.: UTF-16 "willst" du deshalb benutzen, weil es die interne Repräsentation von Zeichen in Windows 2000 aufwärts ist.



  • Vielen Dank.
    Dann sieht es wohl momentan folgendermaßen aus:
    Wenn ich per Compilerswitch Unicode (nicht Multibyte) verwende und statt char wchar_t, dann arbeite ich mit UTF-16?
    Ich hab mir unter den Resourcelinks auf Unicode.org ein kleines Tool runtergeladen, mit dem ich hier auf meinem deutschen System irgendwelche anderen Zeichen (frag mich nciht, welche Sprache das ist 😉 ) eingeben kann. Damit kann ich dann schonmal ein wenig rumtesten.
    Du sagst, UTF-16 benutzt 2 ODER 4 Byte, heisst das, dass wchar_t variabel in der Größe ist oder dass ein Zeichen ein oder zwei wchar_ts benötigt?
    Dann vielleicht noch ne Empfehlung: Wie ist das eBook auf Unicode.org? Meinst du, das ist für mich geeignet, wenn ich im Grunde nur an einer funktionierenden (wenn auch sauberen) Implementierung interessiert bin?


Log in to reply