FindFirstUTF8 und Umlaute?

Rund um die LCL und andere Komponenten
MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: FindFirstUTF8 und Umlaute?

Beitrag von MmVisual »

Wenn zumindest TFileStream und TStringList automatisch UTF8 nach Unicode wandeln würe, dann könnte man das meiste erschlagen, denn nahezu alles kann man über einen Memory/File Stream machen.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
theo
Beiträge: 10904
Registriert: Mo 11. Sep 2006, 19:01

Re: FindFirstUTF8 und Umlaute?

Beitrag von theo »

MmVisual hat geschrieben:Wenn zumindest TFileStream und TStringList automatisch UTF8 nach Unicode wandeln würe,
UTF-8 ist Unicode.
Das Problem ist, dass die RTL unter Windows nicht die Unicode sondern die ANSI Funktionen verwendet.

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: FindFirstUTF8 und Umlaute?

Beitrag von MmVisual »

UTF8 ist doch ein gemischter 8/16 Bit Zeichensatz.
Hingegen Unicode sind alle Zeichen 16 Bit breit.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
theo
Beiträge: 10904
Registriert: Mo 11. Sep 2006, 19:01

Re: FindFirstUTF8 und Umlaute?

Beitrag von theo »

MmVisual hat geschrieben:UTF8 ist doch ein gemischter 8/16 Bit Zeichensatz.
Hingegen Unicode sind alle Zeichen 16 Bit breit.
Ziemlich falsch. UTF-8 ist eine Kodierung. Ein "Code Point" (~Zeichen) kann 1 bis 4 Byte beanspruchen. Gearbeitet wird mit 1Byte Char-Sequenzen (auch AnsiString).

Was du als Unicode bezeichnest ist UCS-2 (resp. UTF-16), welches im WideString, neuerdings auch UnicodeString (fragliche Bezeichnung) abgebildet wird.
Hier wird mit 2Byte pro Char gearbeitet (WideChar).

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: FindFirstUTF8 und Umlaute?

Beitrag von MmVisual »

Ich bin leider auch nicht der Zeichen-Codierungs-Experte.

Einfach ausgedrückt, UFT-8 ist variable länge von 1..4 Byte je Zeichen, Unicode (UTF-16) immer 2 Byte je Zeichen.

Wieder was gelernt :wink:
EleLa - Elektronik Lagerverwaltung - www.elela.de

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: FindFirstUTF8 und Umlaute?

Beitrag von Socke »

mschnell hat geschrieben:Wenn ich mich nicht sehr täusche, muss das Programm (hier also die RTL) in Windows explizit entweder die 8-Bit ANSI-API Funktion oder die 16 Bit (UC-2 / Widestring) ANSI-API aufrufen. Beides ist nicht UTF-8, was die RTL heute verwendet. Die RTL muss also in jedem Fall konvertieren. Ein Unicode-Programm (also die neuere Version der RTL) sollte dann natürlich die Widestring API von Windows verwenden, sonst geht ja das verloren, was Unicode bringen soll.

In Linux ist das natürlich kein Problem, das hier (meist) UTF-8 verwendet wird, genau wie in der RTL. Es ist also keine Konvertierung nötig.
Die RTL verwendet an sich gar keinen Zeichensatz bzw. es ist ihr egal. Alles wir ohne Umwege an das Betriebssystem weitergeleitet (wie oft, habe ich das eigentlich schon geschrieben; bzw. warum schaut hier keiner in den Quellcode?).
Ich sehe auch kein Problem darin, dass die LCL UTF-8 verwendet. Das konvertieren zur System-Kodierung (also UTF-8 oder UTF-16) sollte wohl das geringste Problem bei der Entwicklung von Anwendungen sein.
MmVisual hat geschrieben:Wenn zumindest TFileStream und TStringList automatisch UTF8 nach Unicode wandeln würe, dann könnte man das meiste erschlagen, denn nahezu alles kann man über einen Memory/File Stream machen.
Ich hoffe, du meinst nicht den Inhalt sondern den Dateizugriff. Den Inhalt automatisch zu konvertieren halte ich für sehr problematisch aus Entwicklersicht.
Für den Dateizugriff werden die API-Wrapper-Funktionen der RTL verwendet. D.h. die Dateinamen werden einfach nur ans OS weitergereicht. Das Problem entsteht in erster Linie dadurch, dass die RTL unter Windows die ANIS-Funktionen verwendet (die -- so nehme ich an -- intern auch nur auf die UTF-16-Varianten abbilden).

Vorerst dürfte es am einfachsten sein, wenn man die bereits angesprochene Unit ufiles verwendet oder den Dateizugriff unter Windows manuell über die UTF-16-API gestaltet.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: FindFirstUTF8 und Umlaute?

Beitrag von MmVisual »

Socke hat geschrieben:Ich hoffe, du meinst nicht den Inhalt sondern den Dateizugriff. Den Inhalt automatisch zu konvertieren halte ich für sehr problematisch aus Entwicklersicht.
Für den Dateizugriff werden die API-Wrapper-Funktionen der RTL verwendet. D.h. die Dateinamen werden einfach nur ans OS weitergereicht. Das Problem entsteht in erster Linie dadurch, dass die RTL unter Windows die ANSI-Funktionen verwendet (die -- so nehme ich an -- intern auch nur auf die UTF-16-Varianten abbilden).

Vorerst dürfte es am einfachsten sein, wenn man die bereits angesprochene Unit ufiles verwendet oder den Dateizugriff unter Windows manuell über die UTF-16-API gestaltet.
Natürlich nicht den Inhalt, nur der übergebene Dateiname.

Die API-Wrapper-Funktionen der RTL verwendet offensichtlich nur die Ansi und nicht die Wide-String Funktionen (Windows). Der UFT-8 String wird nur mit UTF8ToSys() konvertiert, daber werden arabische Zeichen zu einem "?" weil die Zeichen in der System Codetabelle des ANSI Zeichensatzes nicht existieren.

Die Unit ufiles funktioniert. Direkt die Windows API verwenden, davon halte ich nichts, damit wäre ich automatsch an Windows gebunden, was ich immer vermeide.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: FindFirstUTF8 und Umlaute?

Beitrag von Socke »

[quote="MmVisual"Die API-Wrapper-Funktionen der RTL verwendet offensichtlich nur die Ansi und nicht die Wide-String Funktionen (Windows). Der UFT-8 String wird nur mit UTF8ToSys() konvertiert, daber werden arabische Zeichen zu einem "?" weil die Zeichen in der System Codetabelle des ANSI Zeichensatzes nicht existieren.

Die Unit ufiles funktioniert. Direkt die Windows API verwenden, davon halte ich nichts, damit wäre ich automatsch an Windows gebunden, was ich immer vermeide.[/quote]
Nochmal: FileOpen() usw. (das sind die API-Wrapper-Funktionen, von denen ich rede), konvertieren gar nichts. Wenn du das aber manuell machst, hast du natürlich recht.

Ich kann mir schlecht vorstellen, dass die Unit ufiles nicht die Win-API verwendet. Warum versuchst du das ganze nicht mit Compiler-Schaltern? Ich hab hier einfach mal FileOpen() für Windows kopiert und nur den Funktionsnamen angepasst. Sehr viel anders kann ufiles das doch auch nicht machen?

Code: Alles auswählen

{$IFDEF WINDOWS}
const
  AccessMode: array[0..2] of Cardinal  = (
    GENERIC_READ,
    GENERIC_WRITE,
    GENERIC_READ or GENERIC_WRITE);
  ShareMode: array[0..4] of Integer = (
               0,
               0,
               FILE_SHARE_READ,
               FILE_SHARE_WRITE,
               FILE_SHARE_READ or FILE_SHARE_WRITE);
Var
  FN : Widestring;
begin
  FN:=UTF8Decode(FileName)+#0;
  result := CreateFileW(@FN[1], dword(AccessMode[Mode and 3]),
                       dword(ShareMode[(Mode and $F0) shr 4]), nil, OPEN_EXISTING,
                       FILE_ATTRIBUTE_NORMAL, 0);      
{$ELSE}
  Result := FileOpen(FileName, Mode);
{$ENDIF}
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: FindFirstUTF8 und Umlaute?

Beitrag von MmVisual »

Ich habe jetzt einmal etwas gegraben und in der Datei: "C:\lazarus\fpc\2.4.2\source\rtl\win32\windows.pp"
folgendes gefunden:

Code: Alles auswählen

{$ifdef UNICODE}
{$i unidef.inc}
{$else not UNICODE}
{$i ascdef.inc}
{$endif UNICODE}
Scheinbar müsste ich irgendwo UNICODE aktivieren können, dann geht alles richtig.
Wo mache ich das :?:

die Technik mit den INC Dateien ist zwar nett, aber erschwert doch die Suche, denn Lazarus öffnet jedesmal die *h.inc Datei mit der Deklaration, aber der Code ist wo ganz anders vergraben.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: FindFirstUTF8 und Umlaute?

Beitrag von Socke »

Du musst die RTL neu übersetzen:

Code: Alles auswählen

make all install INSTALL_PREFIX="mydir/fpc/" OPT="-dUNICODE"
Edit:
Du musst dann unter Windows aber UTF-16 kodierte Strings an die RTL-Funktionen übergeben. Das wäre als Datentyp WideString, Die Funktionen sind aber als (Ansi)String deklariert. Gibt es da nicht eine automatische Konvertierung?
Daher dürfte diese Lösung auch nicht wirklich sauber plattformunabhängig sein.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: FindFirstUTF8 und Umlaute?

Beitrag von MmVisual »

Ja, stimmt. Da müsste die Funktion:

Code: Alles auswählen

Function FileCreate (Const FileName : String) : THandle;
Var
  FN : string;
begin
  FN:=FileName+#0;
  Result := CreateFile(@FN[1], GENERIC_READ or GENERIC_WRITE,
                       0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
end;
der Datei "C:\lazarus\fpc\2.4.2\source\rtl\win\sysutils.pp" noch so abgeändert werden:

Code: Alles auswählen

{$ifdef UNICODE}
 FN:=UTF8Decode(FileName+#0);
{$else not UNICODE}
 FN:=FileName+#0;
{$endif UNICODE}
Und das bei allen RTL-Funktionen
EleLa - Elektronik Lagerverwaltung - www.elela.de

Antworten