Hallo Shardik,
ich habe selbstverständlich auch deinen Code ausprobiert. Allerdings bekomme ich bei DirectoryEntryName() nur mit
aktivierter Unicode-Option Dateinamen mit Umlauten geliefert. Deshalb konnte ich ihn dann leider doch nicht verwenden.
Gruß
Dieter
Fehler nach NewPrinterPage()
-
Dieter
- Beiträge: 22
- Registriert: 14.08.2014 14:32
- Computerausstattung: MacMini (2018 (2020), I7 3.2GHz, 32GB), OSX 10.15.5, PB 5.61 x64 - VmWare-Fusion: Win10 Home Premium, XP Professional
History: ZX81 - ZX Spectrum - Apple II - Atari ST - PC (MS-DOS 3.2 ... WIN 10) - Linux/UNIX - Mac
Re: Fehler nach NewPrinterPage()
MacMini (2020, I7 3.2GHz, 32GB), OSX 10.15.x, PB 5.72 LTS x64 - VmWare-Fusion: Win7 Home Premium, XP Professional, Ubuntu 14.04 - ZX81 - Apple II - Atari ST
Re: Fehler nach NewPrinterPage()
@Shardik:
Ich habe dich ja schon auf den doppelt großen Buffer hingewiesen, der per Space() in deinem Code erzeugt wird.
Damit du ts-soft und mich besser verstehst, habe ich kurz einen Code erstellt, der die Problematik klar veranschaulichen sollte.
Führe diesen Code im Unicode-Modus aus und schau dir die Debug-Ausgabe an:
Als Debug-Ausgabe erhalte ich mit eingeschaltetem Unicode-Modus:
Ich habe dich ja schon auf den doppelt großen Buffer hingewiesen, der per Space() in deinem Code erzeugt wird.
Damit du ts-soft und mich besser verstehst, habe ich kurz einen Code erstellt, der die Problematik klar veranschaulichen sollte.
Führe diesen Code im Unicode-Modus aus und schau dir die Debug-Ausgabe an:
Code: Alles auswählen
Define.s Text, Buffer, Output
Define.i BufferSize, i
;Text = "hr"
Text = "hallo"
Buffer = Space(StringByteLength(Text, #PB_Ascii))
BufferSize = StringByteLength(Buffer) + SizeOf(Character)
Debug "Buffer-Größe: " + BufferSize + " Bytes"
Debug "Variable-Inhalt: " + Text
Debug ""
For i = 0 To BufferSize-1
Select PeekB(@Buffer + i)
Case 32: Output + "[Leerzeichen]"
Case 0: Output + "[Null]"
EndSelect
Next
Debug "Buffer-Inhalt: " + Output
Debug "Wie man sieht, wird zu viel Buffer reserviert und an jedem Leerzeichen noch ein Null-Zeichen angefügt."
Debug "Korrekt wäre:"
Output = ""
For i = 1 To Len(Text)
Output + "[Leerzeichen]"
Next
Output + "[Null]"
Debug "Buffer-Inhalt: " + Output
Debug ""
Debug "Wir füllen den Buffer nun mit dem Inhalt der Text-Variable:"
PokeS(@Buffer, Text, -1, #PB_Ascii)
Output = ""
For i = 0 To BufferSize-1
Byte = PeekB(@Buffer + i)
Select Byte
Case 32: Output + "[Leerzeichen]"
Case 0: Output + "[Null]"
Default: Output + Chr(Byte)
EndSelect
Next
Debug "Buffer-Inhalt: " + Output
Debug "Korrekt wäre:"
Output = Text
Output + "[Null]"
Debug "Buffer-Inhalt: " + Output
Debug ""
Debug "String-Länge mit PB-Len(): " + Len(Buffer)
Debug "Zeichen mit PB-Mid(): " + Mid(Buffer, 1)
Debug "Zeichen mit PB-Left(): " + Left(Buffer, 1)
Debug "Zeichen mit PB-Right(): " + Right(Buffer, 1)
Debug ""
Debug "Es gibt sicherlich noch weitere Funktionen, die eine falsche Ausgabe geben."
Debug "Diese sollten jedoch zur Darstellung der Problematik genügen."Code: Alles auswählen
Buffer-Größe: 12 Bytes
Variable-Inhalt: hallo
Buffer-Inhalt: [Leerzeichen][Null][Leerzeichen][Null][Leerzeichen][Null][Leerzeichen][Null][Leerzeichen][Null][Null][Null]
Wie man sieht, wird zu viel Buffer reserviert und an jedem Leerzeichen noch ein Null-Zeichen angefügt.
Korrekt wäre:
Buffer-Inhalt: [Leerzeichen][Leerzeichen][Leerzeichen][Leerzeichen][Leerzeichen][Null]
Wir füllen den Buffer nun mit dem Inhalt der Text-Variable:
Buffer-Inhalt: hallo[Null][Leerzeichen][Null][Leerzeichen][Null][Null][Null]
Korrekt wäre:
Buffer-Inhalt: hallo[Null]
String-Länge mit PB-Len(): 5
Zeichen mit PB-Mid(): 慨汬o
Zeichen mit PB-Left(): 慨
Zeichen mit PB-Right():
Es gibt sicherlich noch weitere Funktionen, die eine falsche Ausgabe geben.
Diese sollten jedoch zur Darstellung der Problematik genügen.Code: Alles auswählen
Buffer-Größe: 6 Bytes
Variable-Inhalt: hr
Buffer-Inhalt: [Leerzeichen][Null][Leerzeichen][Null][Null][Null]
Wie man sieht, wird zu viel Buffer reserviert und an jedem Leerzeichen noch ein Null-Zeichen angefügt.
Korrekt wäre:
Buffer-Inhalt: [Leerzeichen][Leerzeichen][Null]
Wir füllen den Buffer nun mit dem Inhalt der Text-Variable:
Buffer-Inhalt: hr[Null][Null][Null][Null]
Korrekt wäre:
Buffer-Inhalt: hr[Null]
String-Länge mit PB-Len(): 1
Zeichen mit PB-Mid(): 牨
Zeichen mit PB-Left(): 牨
Zeichen mit PB-Right(): 牨
Es gibt sicherlich noch weitere Funktionen, die eine falsche Ausgabe geben.
Diese sollten jedoch zur Darstellung der Problematik genügen.

Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
- ts-soft
- Beiträge: 22292
- Registriert: 08.09.2004 00:57
- Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel - Wohnort: Berlin
Re: Fehler nach NewPrinterPage()
Einfache Sache: Wir kompilieren im Unicode-Modus, das heißt alle Strings sind im Unicode-Modus, es gibt
keine Strings neben mir.
@ASCIIText könnte als Buffer für ASCII dienen, aber ASCIIText.s ist nicht mehr nutzbar!
Du übergibst ASCIIText.s an DrawText(...), welches ungültig sein könnte, da nur Unicode-Strings verwaltet
werden. Den Buffer dürftest Du übergeben, aber der wird ja von DrawText() nicht erwartet.
Okay, der Stringmanager merkt es nicht, da keine Aktion und die defekte API auch nicht, so funktioniert der
Code, mehr oder weniger, zufällig.
Also: Für Buffer anderer Encoding besser Speicher verwenden. Wenn Buffer per Spaces genutzt wird, dann
nur den Buffer nutzen und niemals den String!
Gruß
Thomas
keine Strings neben mir.
Code: Alles auswählen
ASCIIText = Space(StringByteLength(Text, #PB_Ascii))Du übergibst ASCIIText.s an DrawText(...), welches ungültig sein könnte, da nur Unicode-Strings verwaltet
werden. Den Buffer dürftest Du übergeben, aber der wird ja von DrawText() nicht erwartet.
Okay, der Stringmanager merkt es nicht, da keine Aktion und die defekte API auch nicht, so funktioniert der
Code, mehr oder weniger, zufällig.
Also: Für Buffer anderer Encoding besser Speicher verwenden. Wenn Buffer per Spaces genutzt wird, dann
nur den Buffer nutzen und niemals den String!
Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.

Re: Fehler nach NewPrinterPage()
Vielen Dank Sicro, für Dein tolles ausführliches Beispiel, das alles wunderbar klar macht und Danke an Thomas für Deine zusätzlichen Erläuterungen.
Der Grund für den "Missbrauch" eines Unicode-Strings war einfach meine Bequemlichkeit: ich brauche keinen Speicherpuffer mit AllocateMemory() anlegen und vor allem später nicht daran denken, diesen wieder freizugeben. Mein Denkfehler lag darin, dass StringByteLength(String, #PB_Ascii) ja korrekt die Länge eines ASCII-Strings angibt, aber Space(StringByteLength(Text, #PB_Ascii)) ja doch wieder im Unicode-Modus die doppelte benötigte Länge anlegt. Dass man mit einem ASCII-String im Unicode-Modus keine String-Operationen durchführen kann, war mir natürlich klar.
In einem früheren Beispiel im englischen Forum hatte ich daher auch im Unicode-Modus die ermittelte Länge für Space() durch 2 dividiert:
Was haltet ihr davon? Die Länge des "missbrauchten" Unicode-Strings ASCIIText ist dann korrekt und der Buffer-Inhalt in Sicros Beispiel wäre dann auch im Unicode-Modus hinterher korrekt. Natürlich ist klar, dass mit der Space()-Funktion im Unicode-Modus der String ASCIIString nicht mit einem korrekten ASCII-String gefüllt ist, aber er dient ja auch nur als Speicherpuffer in der benötigten Größe. Und natürlich funktionieren die String-Operationen nicht, aber man würde ja auch mit einem Speicher-Puffer keine String-Operationen durchführen wollen. Natürlich würde der Einwand von Thomas noch immer gelten, dass DrawText() keinen Buffer erwartet sondern einen String, aber es funktioniert ja trotzdem. Zugegebenermaßen würden Probleme auftreten, wenn Fred den Stringmanager in neueren PB-Versionen verändern oder "schärfere" Prüfungen einbauen würde...
Der Grund für den "Missbrauch" eines Unicode-Strings war einfach meine Bequemlichkeit: ich brauche keinen Speicherpuffer mit AllocateMemory() anlegen und vor allem später nicht daran denken, diesen wieder freizugeben. Mein Denkfehler lag darin, dass StringByteLength(String, #PB_Ascii) ja korrekt die Länge eines ASCII-Strings angibt, aber Space(StringByteLength(Text, #PB_Ascii)) ja doch wieder im Unicode-Modus die doppelte benötigte Länge anlegt. Dass man mit einem ASCII-String im Unicode-Modus keine String-Operationen durchführen kann, war mir natürlich klar.
In einem früheren Beispiel im englischen Forum hatte ich daher auch im Unicode-Modus die ermittelte Länge für Space() durch 2 dividiert:
Code: Alles auswählen
CompilerIf #PB_Compiler_Unicode
ASCIIText = Space(StringByteLength(Text, #PB_Ascii) / 2)
PokeS(@ASCIIText, Text, -1, #PB_Ascii)
CompilerElse
ASCIIText = Text
CompilerEndIfRe: Fehler nach NewPrinterPage()
So ist es schon viel besser. Im Buffer ist dann nur noch maximal ein Byte zu viel, wenn die String-Länge eine geradene Zahl ist.Shardik hat geschrieben:Code: Alles auswählen
ASCIIText = Space(StringByteLength(Text, #PB_Ascii) / 2)

Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version