Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

GR-PA

Treue Seele

  • »GR-PA« ist der Autor dieses Themas

Beiträge: 326

Wohnort: Daheim

Beruf: Faulenzer

  • Private Nachricht senden

1

03.02.2008, 11:14

Unicode

Hallo,

Mir ist aufgefallen, das immer wieder Fragen gestellt werden, in denen Leute bei Fehlern im Zusammenhang mit Unicode nicht weiterkommen. Deshalb will ich hier kurz erläutern, wie man alle Fehler mit Unicode ganz einfach umgehen kann.

Zuerst will ich erwähnen, dass man Unicode beliebig in seinem Programm ein oder ausschalten kann. Das geht folgendermaßen:
Man geht auf Projekt/Eigenschaften/Konfigurationseigenschaften/Allgemein und wählt im Feld Zeichensatz entwerde Unicode oder Multi-Byte aus.

Man kann zwar alle Probleme mit Unicode aus der Welt schaffen, indem man Unicode einfach ausschaltet. Das das keine gute Lösung ist, kann man am besten anhand eines Beispiels erläutern:

Angenommen ihr wollt ein Programm schreiben. Dieses Programm soll zum einen in einer Sprache verfügbar sein, die die lateinischen Schriftzeichen verwendet (also Deutsch, Englisch, ...) und zum anderen in einer östlichen Sprache (z.B. Japanisch) die ein ganz anderes Alphabet von Schriftzeichen verwendet. Bei der Verwendung von Multi-Byte müsste man nun das Programm zweimal, nämlich unter einem Betriebssystem mit der einen und anschließend auf einem Betriebssystem mit der anderen Sprache kompilieren. Um dieses Problem zu umgehen verwendet man Unicode.

Außerdem beugt man viele Fehler vor, wenn man z.B. eine Engine so gestaltet, dass sie sowohl mit als auch ohne Unicode zurecht kommt.

Nun kommen wir zum ersten Problem.
Oft verzweifeln Leute an Fehlermeldungen à la

Zitat

MessageBoxW: Konventierung des zweiten Parameters von LPCSTR in LPCWSTR nicht möglich
Diese Fehlermeldung liegt daran, dass Unicode-Zeichen (auch als breite Zeichen bezeichnet) viel mehr Speicher belegen, wie Multi-Byte Zeichen. Deshalb gibt es für Unicode spezielle Datentypen. Da es aber ein besserer Stil ist, Datentypen einzusetzen, die je nachdem, ob Unicode eingestellt ist oder nicht für Unicode oder Multi-Byte-Zeichen stehen. Diesen Datentyp gibt es nur für einzelne Schriftzeichen aber nicht für Strings er lautet:

C-/C++-Quelltext

1
TCHAR // steht bei eingestelltem Multi-Byte für char und bei eingestelltem Unicode für das Pendant wchar_t


Für Unicode-Strings gibt es die Datentypen:
PCWSTR
LPCWSTR

bei Multi-Byte sind das:
PCSTR
LPCSTR

Unicode Strings haben noch eine Besonderheit. Vor ihnen muss immer ein L stehen. Das sieht dann so aus:

C-/C++-Quelltext

1
L"Text"

bzw.:

C-/C++-Quelltext

1
L'Zeichen'


Folgender Code führt also bei eingestelltem Unicode zur obigen Fehlermeldung:

C-/C++-Quelltext

1
MessageBox(NULL, "Text", "Text", 0);


Wenn man nun ein L vor die Strings setzt, ist der Fehler behoben, aber wenn man nun Multi-Byte einstellt, kommt folgende Fehlermeldung:

Zitat

MessageBoxA: Konventierung des Parameters 2 von LPCWSTR in LPCSTR nicht möglich


An dieser Stelle möchte ich noch kurz erwähnen, wofür das W und das A stehen, wenn man doch nur MessageBox benutzt hat. Das liegt daran, das MessageBox je nachdem ob Unicode definiert ist oder nicht Als MessageBoxA(Multi-Byte Version) oder MessageBoxW(Unicode-Version) definiert ist.

Hier kommmt nun ein Makro ins Spiel, das in WinDef.h definiert ist. Da WinDef.h von windows.h eingebunden wird, muss man also keine weiteren Headerdateien einbinden. Das Makro setzt je nachdem, ob Unicode Definiert ist ein L vor den String oder nicht. Das Makro wird wie folgt verwendet:

C-/C++-Quelltext

1
TEXT("Text")


Also muss man einfach immer, wenn eine Funktion eine Unicode und eine Multi-Byte Variante hat den Text über das Makro TEXT übergeben und schon ist man alle Probleme mit Unicode los und kann die Vorteile die der erweiterte Zeichensatz bietet in vollen Zügen ausnutzen.

Das Beispiel mit MessageBox würde dann wie folgt aussehen:

C-/C++-Quelltext

1
MessageBox(NULL, TEXT("Text"), TEXT("Text"), 0)


zugegeben, es ist Gewohnheitssache, aber es lohnt sich.
Signaturen werden überbewertet

spacegaier

Alter Hase

Beiträge: 572

Beruf: Student

  • Private Nachricht senden

2

03.02.2008, 11:18

Gute Idee!

-> Ab in die FAQ würd ich sagen (oder gleich Tut-Sektion).

Chase

Alter Hase

Beiträge: 753

Wohnort: Nagaoka / Darmstadt / Düsseldorf

Beruf: fauler Studi

  • Private Nachricht senden

3

03.02.2008, 11:25

Ich bin mir nicht sicher, aber gab es nicht irgendeine Option die

Quellcode

1
"Text"
immer in Unicode umwandelt? Also ohne ein laestiges L davor, und ohne Makros? Auf Multibyte kann man naemlich imo heutzutage verzichten!
"Have you tried turning it off and on again?"

ChrisJ

Alter Hase

Beiträge: 487

Wohnort: Schweich

Beruf: Schüler

  • Private Nachricht senden

4

03.02.2008, 11:46

das glaube ich nicht.
was wäre denn, wenn du printf("hi"); aufrufen willst, und der string automatisch ein unicode string ist?
"Don't trust your eyes: They are a hell of a lot smarter than you are"

GR-PA

Treue Seele

  • »GR-PA« ist der Autor dieses Themas

Beiträge: 326

Wohnort: Daheim

Beruf: Faulenzer

  • Private Nachricht senden

5

03.02.2008, 11:51

Zitat von »"Chase"«

Auf Multibyte kann man naemlich imo heutzutage verzichten!

Angenommen, du hättest eine Engine erstellt, die auch andere Leute außer dir benutzen. Dann benutzt die jemand, der Multi-Byte verwenden will, und wundert sich, weshalb er ~100 Fehlermeldungen bekommt. Es stimmt zwar, dass Multi-Byte für die Programmierung unter Windows mehr oder weniger unnötig ist, aber z.B. kann man in Konsolenanwendungen kein Unicode benutzen und ist auf Multi-Byte angewiesen.
Signaturen werden überbewertet

6

03.02.2008, 12:38

std::wcout rocks ...
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

Chase

Alter Hase

Beiträge: 753

Wohnort: Nagaoka / Darmstadt / Düsseldorf

Beruf: fauler Studi

  • Private Nachricht senden

7

03.02.2008, 12:43

Zitat von »"Deviloper"«

std::wcout rocks ...

Das wird dann aber ungewandelt, oder? Unicode-Zeichensatz in der Konsole hab ich noch nie gesehen...
(obwohl sich das auf lange Sicht auch aendern muss)
"Have you tried turning it off and on again?"

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

8

03.02.2008, 13:28

Zitat von »"Chase"«

Auf Multibyte kann man naemlich imo heutzutage verzichten!


Unsinn. Wieso sollte man auf Multibyte verzichten? Wie oft hattest du den Fall das du Unicode tatsächlich benötigt hast? Und wieso sollte man mehr Speicher verbraten als notwendig?
@D13_Dreinig

Faule Socke

Community-Fossil

Beiträge: 1 915

Wohnort: Schreibtischstuhl

  • Private Nachricht senden

9

03.02.2008, 13:41

Ich bin mit David einer meinung. Gerade bei Engines reicht es oft aus, einen (const) char* zu verwenden, um zum Beispiel ein Objekt anhand eines Namens zu identifizieren. Unicode kann ja manchmal ganz nützlich sein, ist aber oft auch überflüssig.

Ausserdem denkt ihr viel zu nah an Windows. Es gibt auch noch andere Systeme und diese haben Teilweise auch eine Konsole, die Unicode unterstüzt. Daher kommt warscheinlich auch std::wcout, würde ich vermuten, einfach um allgemein zu bleiben. Wenn windows das nicht unterstüzt, ist das ja nciht das Problem der C++ STDLIB.

Socke

GR-PA

Treue Seele

  • »GR-PA« ist der Autor dieses Themas

Beiträge: 326

Wohnort: Daheim

Beruf: Faulenzer

  • Private Nachricht senden

10

03.02.2008, 14:00

Und aus genau diesem Grund habe ich nicht nur erklärt, wie man Unicode verwendet, sondern auch, wie man seinen Code allgemeingültig hält. So kann man von Fall zu Fall selbst entscheiden ob Unicode sinvoll ist oder nicht und kann trotzdem den gleichen Code verwenden, den man auch verwendet, wenn man Unicode benutzt.
Signaturen werden überbewertet

Werbeanzeige