Autor Beitrag
Mortal-Shadow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 110



BeitragVerfasst: Mi 27.05.09 13:43 
Hi,

zwecks Datenübertragung arbeitet Narses in seinem Tut so:
ausblenden Delphi-Quelltext
1:
2:
SetLength(BinMsg,4);
PInteger(@BinMsg[1])^ := MyInt;

bevor er BinMsg als String sendet.
Nun wollte ich so einen Real übertragen:
ausblenden Delphi-Quelltext
1:
2:
SetLength(BinMsg,8);
PReal(@BinMsg[1])^ := MyReal;

Leider gibt es PReal nicht.
Kann ich das irgendwie umgehen?

Mfg.


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Mi 27.05.2009 um 14:07
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 27.05.09 13:57 
Du könntest es deklarieren. ;-)
ausblenden Delphi-Quelltext
1:
2:
type
  PReal = ^Real;
Oder du könntest einen "richtigen" Typ wie Single oder Double nehmen, da sind die Pointertypen bereits deklariert...
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 27.05.09 14:11 
Moin!

user profile iconMortal-Shadow hat folgendes geschrieben Zum zitierten Posting springen:
zwecks Datenübertragung arbeitet Narses in seinem Tut so:
[...]
Nun wollte ich so einen Real übertragen:
[...]
Leider gibt es PReal nicht.
Kann ich das irgendwie umgehen?
Real ist ein generischer Datentyp, den du nicht in so einem Kontext verwenden solltest, wo es auf das Bytelayout im RAM ankommt :!:
In diesem Fall Single, Double oder Extended verwenden (und diese Typen sind im TProtocolAdapter bereits drin). :idea: ;)

(btw: war Real nicht eh deprecated? :gruebel:)
(//EDIT: kann sein, das war Real48... :?)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.


Zuletzt bearbeitet von Narses am Mi 27.05.09 14:21, insgesamt 1-mal bearbeitet
Mortal-Shadow Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 110



BeitragVerfasst: Mi 27.05.09 14:16 
Ok, das ist ja nicht das Problem.
Laut Delphi-Hilfe sind Real und Double eh gleich:
Zitat:

The generic type Real, in its current implementation, is equivalent to Double.

Btw: wenn es gleich ist - warum sollte es dann nicht verwendet werden?
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 27.05.09 14:22 
Moin!

user profile iconMortal-Shadow hat folgendes geschrieben Zum zitierten Posting springen:
Btw: wenn es gleich ist - warum sollte es dann nicht verwendet werden?
Weil es in einer zukünftigen Delphi-Version eben nicht mehr Double, sonder Extended oder Hyperble oder ... sein könnte. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 27.05.09 14:23 
Den entscheidenden Teil hast du selbst geschrieben:
user profile iconMortal-Shadow hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:

The generic type Real, in its current implementation, is equivalent to Double.
Du weißt nicht wann sich das ändert und weißt im Grunde nichts genaues über den Datentyp...
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: Mi 27.05.09 16:06 
Die Lösung ist einfach:
ausblenden Delphi-Quelltext
1:
2:
SetLength(BinMsg,sizeof(MyReal));
move(@BinMsg[1], MyReal, sizeof(MyReal));


Gruß Gammatester
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 27.05.09 17:04 
Moin!

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Die Lösung ist einfach
...keine gute Idee, um hier keine Zweifel aufkommen zu lassen. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: Mi 27.05.09 18:22 
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Moin!

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Die Lösung ist einfach
...keine gute Idee, um hier keine Zweifel aufkommen zu lassen. ;)

cu
Narses


Und was soll daran keine "gute Idee" sein? Hat man Dir eingeimpft, "move" ist böse? Das ist richtig, wenn man nicht weiß, was man tut, oder wenn man nicht weiß, wohin man schreibt. Beides ist hier nicht der Fall: Ich weiß, was ich tue, und der Speicherplatz ist da. Im übrigen dies sogar besser als die vorgestellten Lösungsversuche via Pointer/Typecast, da dort setlength mit fixer Länge benutzt wird und dann kann's wirklich krachen.

Gammatester
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Mi 27.05.09 23:16 
Moin!

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Und was soll daran keine "gute Idee" sein?
Da du scheinbar Probleme beim Lesen hast, hier nochmal extra für dich: :)
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
The generic type Real, in its current implementation, is equivalent to Double.
Du weißt nicht wann sich das ändert und weißt im Grunde nichts genaues über den Datentyp...
Demnächst bitte lesen und verstehen, bevor du auf die Barrikaden gehst. :|

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Hat man Dir eingeimpft, "move" ist böse?
[...]
Ich weiß, was ich tue
Scheinbar nicht, zumindest fehlt dir entscheidende Einsicht in das angesprochene Tutorial. :nixweiss:

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Im übrigen dies sogar besser als die vorgestellten Lösungsversuche via Pointer/Typecast, da dort setlength mit fixer Länge benutzt wird und dann kann's wirklich krachen.
Nein, es ist weder besser noch schlechter, es ist schlicht gleichwertig - wenn man nicht auf generische Typen setzt. Und genau das ist es, was ich hier die ganze Zeit sage... :roll: es geht im Tutorial nämlich unter Anderem darum, eine vorhersagbare Anzahl Bytes pro Frame zu bekommen - das geht aber mit deiner Lösung nicht, da generische Typen unsicher/unbekannt (in diesem Zusammenhang) sind; aber erstmal draufhauen, auch wenn man nicht weiß, worum es eigentlich geht... *seufz*

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: Do 28.05.09 09:56 
Ich sehe zwar nicht, warum ich entscheidende Einblicke in Dein Tutorial nehmen soll, um solche einfache Aufgaben zu beantworten, habe es jetzt aber runtergeladen und mal die angesprochene Stelle angesehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
// Button-Aktion ausführen -> Text senden
procedure TForm1.Button1Click(Sender: TObject);
var
BinMessage: String;
begin
SetLength(BinMessage,4); // String mit 4 Zeichen Länge erzeugen
PInteger(@BinMessage[1])^ := Length(Edit1.Text); // Länge des Textes eintragen
BinMessage := BinMessage +Edit1.Text; // Text selbst anfügen
ClientSocket1.Socket.SendText(BinMessage); // komplette Zeichenkette senden
end;

Leider muß ich feststellen, daß das angebotene noch schlechter ist als ich gedacht habe. Nicht nur, daß Du genau den Fehler machst, den Du anprangerst (Verwendung von generischen Typen unter Annahme einer festen Größe, und integer ist ja wohl der generische Typ schlechthin), nein: es wird darüber hinaus wieder einmal der Typ String zur Verarbeitung/Transport von Binärdaten benutzt.
Zitat:
es geht im Tutorial nämlich unter Anderem darum, eine vorhersagbare Anzahl Bytes pro Frame zu bekommen - das geht aber mit deiner Lösung nicht, da generische Typen unsicher/unbekannt (in diesem Zusammenhang) sind;

Mit Deiner Lösung geht es wie gesagt auch nicht. Wenn Du es besser machen willst, solltest Du eine Hilfsvariable einführen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var
  TxtLen: longint;
{...}
  TxtLen := Length(Edit1.Text);  {Hoffentlich nicht mehr als 2GB}
  PLongint(@BinMessage[1])^ := Txtlen;


Zitat:
aber erstmal draufhauen, auch wenn man nicht weiß, worum es eigentlich geht... *seufz*

Wo habe ich auf wen drauf gehauen? Das die beschriebene Lösung mit Sicherheit keinen Speicher überschreibt, wirst Du ja wohl zugeben müssen. Und warum sie dann nicht besser sein soll, als die bei denen das passieren kann, ist nicht einsehbar.

Gammatester
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 28.05.09 10:17 
user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Ich sehe zwar nicht, warum ich entscheidende Einblicke in Dein Tutorial nehmen soll, um solche einfache Aufgaben zu beantworten, habe es jetzt aber runtergeladen und mal die angesprochene Stelle angesehen:

Ein Tutorial zu lesen ide die Kurzform von RTFM. Hilft also oftmals ;-)

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
// Button-Aktion ausführen -> Text senden
procedure TForm1.Button1Click(Sender: TObject);
var
BinMessage: String;
begin
SetLength(BinMessage,4); // String mit 4 Zeichen Länge erzeugen
PInteger(@BinMessage[1])^ := Length(Edit1.Text); // Länge des Textes eintragen
BinMessage := BinMessage +Edit1.Text; // Text selbst anfügen
ClientSocket1.Socket.SendText(BinMessage); // komplette Zeichenkette senden
end;

Leider muß ich feststellen, daß das angebotene noch schlechter ist als ich gedacht habe. Nicht nur, daß Du genau den Fehler machst, den Du anprangerst (Verwendung von generischen Typen unter Annahme einer festen Größe, und integer ist ja wohl der generische Typ schlechthin),

Gut, die 4 könnte man durch ein SizeOf(Longint) ersetzen und PInteger durch PLongint, aber eine Umstellung von Integer auf 64 Bit wird so schnell nicht erfolgen.

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
nein: es wird darüber hinaus wieder einmal der Typ String zur Verarbeitung/Transport von Binärdaten benutzt.

Sorry, wenn man keine Ahnung hat ;-)

Zu der Problematik zwecks Strings und Binärdaten habe ich mich durchaus schon mit user profile iconNarses unterhalten und dabei kam relativ eindeutig raus, dass die String-API von Delphi für die verwendeten Funktionen Binary Safe ist. Zumal: Was würde es deiner Ansicht nach besser machen, wenn an jeder Stelle mit PChar und einem manuellen Malloc rumgefrickelt wird? Das einzige Problem mit String ist die Multi-Byte-Änderung in D2k9; die lässt sich aber mit einer Einfachen Änderung von String auf AnsiString korrigieren. Ein Array of Byte bietet prinzipiell ähnliche Möglichkeiten; vom Pointer-Gefrickel unterscheidet sich das aber von Strings in keinster Weise.

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
es geht im Tutorial nämlich unter Anderem darum, eine vorhersagbare Anzahl Bytes pro Frame zu bekommen - das geht aber mit deiner Lösung nicht, da generische Typen unsicher/unbekannt (in diesem Zusammenhang) sind;

Mit Deiner Lösung geht es wie gesagt auch nicht. Wenn Du es besser machen willst, solltest Du eine Hilfsvariable einführen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var
  TxtLen: longint;
{...}
  TxtLen := Length(Edit1.Text);  {Hoffentlich nicht mehr als 2GB}
  PLongint(@BinMessage[1])^ := Txtlen;

Wozu die Hilfsvariable? Ohne die ist durch den Typecast eh der Ziel-Datentyp vorgegeben; da bedarf es keiner Variable um etwas festzustellen, was eh bekannt ist.

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
aber erstmal draufhauen, auch wenn man nicht weiß, worum es eigentlich geht... *seufz*

Wo habe ich auf wen drauf gehauen? Das die beschriebene Lösung mit Sicherheit keinen Speicher überschreibt, wirst Du ja wohl zugeben müssen. Und warum sie dann nicht besser sein soll, als die bei denen das passieren kann, ist nicht einsehbar.

Gammatester


user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Und was soll daran keine "gute Idee" sein? Hat man Dir eingeimpft, "move" ist böse? Das ist richtig, wenn man nicht weiß, was man tut, oder wenn man nicht weiß, wohin man schreibt. Beides ist hier nicht der Fall: Ich weiß, was ich tue, und der Speicherplatz ist da. Im übrigen dies sogar besser als die vorgestellten Lösungsversuche via Pointer/Typecast, da dort setlength mit fixer Länge benutzt wird und dann kann's wirklich krachen.

Gammatester

Ist sie eben nicht, da du mit Move die Möglichkeit zur Typprüfung der Daten verlierst, weshalb eben der Compiler NICHT prüfen kann, ob der Platz ausreicht, was mit der Typecast-Variante durchaus möglich wäre, zudem sogar mit ggf. einer Konvertierung der Daten, sollte noch etwas fehlen.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 28.05.09 10:39 
Moin!

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
mal die angesprochene Stelle angesehen
Du hast zwar nicht die angesprochene Stelle zitiert, aber als Beispiel soll das ausreichen. ;)

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
es wird darüber hinaus wieder einmal der Typ String zur Verarbeitung/Transport von Binärdaten benutzt.
Deine Aussage beweist, dass du wohl eher mit Vorstellungen "geimpft" worden bist, die du besser nochmal auf den Prüfstand stellen solltest. :| Auch hier würde es helfen, das Tutorial mal genauer anzusehen. ;)

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Wenn Du es besser machen willst, solltest Du
...besser AnsiString verwendet haben, das ist richtig. Das Tutorial ist allerdings entstanden, bevor D2k9 rauskam. Da es aber OpenSource ist, darf der geneigte Leser das gerne selbst durchführen.

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Das die beschriebene Lösung mit Sicherheit keinen Speicher überschreibt, wirst Du ja wohl zugeben müssen.
Das habe ich doch nie bezweifelt. ;) Und ja, dein Ansatz ist sowohl syntaktisch als auch konzeptionell funktionsfähig, auch das habe ich nicht bestritten. Allerdings ist er - wie user profile iconBenBE bereits erläutert hat - nicht typensicher und darüber hinaus auch nicht performant: wir reden hier über CPU-native Datentypen, warum soll ich zum Schreiben/Lesen solcher Daten eine Kopierschleife aufrufen, wenn das die CPU auch in einem (logischen) Schritt tun kann? :zwinker:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: Do 28.05.09 11:08 
Zu letzten Mal: der Thread handelt doch wohl nicht davon, ein Tutorial zu lesen, sondern um die konkrete Aufgabe, die Bytes (ja Bytes, nicht chars) einer Real-Variable in einen Speicherbreich zu bewegen.
user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:

Ist sie eben nicht, da du mit Move die Möglichkeit zur Typprüfung der Daten verlierst, weshalb eben der Compiler NICHT prüfen kann, ob der Platz ausreicht, was mit der Typecast-Variante durchaus möglich wäre, zudem sogar mit ggf. einer Konvertierung der Daten, sollte noch etwas fehlen.

Das ist mit der Narses-Variante auch nicht möglich, weil der ganz schöne Check-Mechanismus via Pointertypecast ausgehebelt wird. Nur kommt bei dieser Variante eben noch Pointer-Frickelei (wie Du Dich ausdrückst) ins Spiel, die anschließend groß und breit erklärt werden muß. Ein saubere und professionelle Lösung wäre wie gesagt, keine Strings zu verwenden, sondern zB Records.

Da das aber alles mit PReal()^ nicht mehr viel zu tun, soll's das von mir aus gewesen sein.

Gammatester
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 28.05.09 11:17 
Moin!

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
der Thread handelt doch wohl nicht davon, ein Tutorial zu lesen,
Der Thread bezieht sich ganz konkret auf ein bestimmtes Tutorial. Wie soll man also brauchbar darüber diskutieren, wenn man es nicht kennt... :nut: :zwinker:

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
sondern um die konkrete Aufgabe, die Bytes (ja Bytes, nicht chars) einer Real-Variable in einen Speicherbreich zu bewegen.
Das ist deine Interpretation davon, das haben wir schon bemerkt, ja. :roll:

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
weil der ganz schöne Check-Mechanismus via Pointertypecast ausgehebelt wird.
Ein Typecast ist das Erzwingen eines Typs, nicht das "Aushebeln", irgendwie hast du da scheinbar was falsch verstanden. :idea:

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Ein saubere und professionelle Lösung wäre wie gesagt, keine Strings zu verwenden, sondern zB Records.
Dazu gibt´s auch einen FAQ-Beitrag, den ich dir mal ans Herz legen möchte :les: ach sorry, vergiss es wieder, du liest ja nicht so gerne, ich vergaß... :flehan:

cu :wave:
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: Do 28.05.09 12:29 
Bei soviel Sarkasmus und Ignoranz dann doch ein allerletzen Mal.

1. Die Originalfrage war:
Zitat:
Leider gibt es PReal nicht.
Kann ich das irgendwie umgehen?
Darauf habe ich exakt, vollständig, fehlersicher geanwortet.

2. Du brauchst mir nicht zu erklären, was ein Typecast ist. Fakt ist, daß durch Deine Typecast-Verwendung ein Check nicht möglich ist. Eben weil ein Pointer-Typecast verwendet wird und kein Typcast für den Basistyp.

3. Zu Records, FAQ, etc: Das Records sind kein brauchbarer Ersatz für ein Protokoll sind, ist doch wohl offensichtlich - allerdings Strings noch weniger. Wenn man Deine Ausführung liest, könnte man sich fragen, warum denn überhaupt Records gebraucht werden, und ob man nicht aus den Delphi-, WIN32-APIs etc die Records und structs entfernen sollte.

4. Laß uns ohne Polemik übereinstimmen, daß wir nicht übereinstimmen.
Mortal-Shadow Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 110



BeitragVerfasst: Do 28.05.09 12:55 
So, die Diskussion hat mich jetzt auf eine andere Frage gebracht: (Wenn ich ein neues Thema aufmachen soll, bitte sagen)
Und zwar wegen string vs Ansistring.
Ab D2009 ist string ein unicodestring.
Aber was verändert sich dadurch für die übertragung?
Soweit ich das bei google gefunden habe, ist dass nur eine Performance-Verbesserung, da bei unicode delphi selbst die
Referenzen zählt, bei ansi das betriebssystem.
Das dürfte aber doch auf die übertragung keinen einfluss haben, oder?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 28.05.09 13:12 
user profile iconMortal-Shadow hat folgendes geschrieben Zum zitierten Posting springen:
Soweit ich das bei google gefunden habe, ist dass nur eine Performance-Verbesserung, da bei unicode delphi selbst die
Referenzen zählt, bei ansi das betriebssystem.
Äh, nein. AnsiStrings (der normale String bis Delphi 2007) und die neuen UnicodeStrings werden von Delphicode verwaltet, inkl. Referenzzählung.

WideStrings dagegen, die es als Unicode auch vor Delphi 2009 bereits gab, sind lediglich Wrapper um die vom Betriebssystem angebotenen Unicode-Zeichenketten. Diese haben keinen Referenzzähler.

Der Unterschied zwischen AnsiString und UnicodeString ist, dass AnsiStrings auch AnsiChars enthalten, die jeweils ein Byte pro Zeichen belegen. UnicodeStrings hingegen enthalten die neuen Chars, die mehr als ein Byte belegen. In der aktuellen Implementierung 2 Byte. heißt: Die Größe des belegten Speichers in Byte bei AnsiStrings ist gleich der Länge des Strings. Bei UnicodeStrings hingegen bei 2 Byte pro Buchstaben zweimal so viel. Das muss man bei Speicheroperationen bedenken.

Allgemein kann man die Größe des Speichers aus der Größe eines Buchstabens berechnen:
ausblenden Delphi-Quelltext
1:
MemorySize := Length(DeinString) * SizeOf(Char);					
bzw. umgekehrt
ausblenden Delphi-Quelltext
1:
StringLength := MemorySize div SizeOf(Char);					
Auf diese Weise kann man den selben Code unter Delphi 2007 und früher und Delphi 2009 und später nutzen. Allerdings dürfen dann bei Netzwerk- und Interprozesskommunikation nicht Unicode und Nicht-Unicode Programme gemischt werden, da das natürlich nicht kompatibel ist.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 28.05.09 13:29 
Moin!

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Bei soviel Sarkasmus und Ignoranz
Ignoranz? Nein, sich nicht auf Schablonen-Denken einlassen: ja. ;)

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
dann doch ein allerletzen Mal.
Ich geb´ dir mal einen guten Rat für´s Leben: sieh zu, dass du immer steigerungsfähig bleibst. :zwinker:

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Die Originalfrage war:
Zitat:
Leider gibt es PReal nicht.
Kann ich das irgendwie umgehen?
Darauf habe ich exakt, vollständig, fehlersicher geanwortet.
Die Originalfrage bezog sich konkret auf eine Anwendung im Rahmen eines Tutorials, das du nicht lesen willst. :nixweiss: Dein Vorschlag ist zwar syntaktisch korrekt, aber konzeptionell, performancetechnisch und typenbasiert keine gute Idee im Rahmen des genannten Tuts. Offensichtlich reden wir hier aneinander vorbei.

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Du brauchst mir nicht zu erklären, was ein Typecast ist.
Scheinbar schon: ;)
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
  var
    PInt: PInteger;
    Float: Double;
begin
  PInt^ := Float;
Delphi-Compiler hat folgendes geschrieben:
[Fehler] Unit1.pas(xx): Inkompatible Typen: 'Integer' und 'Double'


user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Das Records sind kein brauchbarer Ersatz für ein Protokoll sind, ist doch wohl offensichtlich - allerdings Strings noch weniger.
Leider muss ich auch hier wieder korrigieren: Ich verwende Strings als Datencontainer, nicht als Protokoll, du vergleichst hier Äpfel mit Birnen. :nixweiss:

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Wenn man Deine Ausführung liest, könnte man sich fragen, warum denn überhaupt Records gebraucht werden, und ob man nicht aus den Delphi-, WIN32-APIs etc die Records und structs entfernen sollte.
Ich kann dir nicht folgen. :?

user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
Laß uns ohne Polemik übereinstimmen, daß wir nicht übereinstimmen.
Jap, das lässt sich manchmal nicht vermeiden. ;)

---

user profile iconMortal-Shadow hat folgendes geschrieben Zum zitierten Posting springen:
Und zwar wegen string vs Ansistring.
Ab D2009 ist string ein unicodestring.
Aber was verändert sich dadurch für die übertragung?
[...]
Das dürfte aber doch auf die übertragung keinen einfluss haben, oder?
Es ändert sich leider sehr viel, da ich die Strings als Datenlager (in diesem Sinne) "missbrauche". Es kommt also im Rahmen des BinProto-Tutorials bei den Strings nur darauf an, dass diese eine bestimmte Menge Daten (hier: Bytes) per Compiler-Magic automatisch verwalten. Deshalb ist der Ansatz darauf ausgelegt, dass ein AnsiString (1-Byte-String) verwendet wird, mit einem Unicode-String wird das nicht funktionieren. user profile iconGammatester wird jetzt vielleicht fett grinsen, da er genau das als "Sünde" einstuft, aber unter der Annahme, dass String=AnsiString gilt (was man ab D2k9 jetzt halt nächträglich im Tut ändern muss), ist es die einfachste Variante, um mit Speicherblöcken zu hantieren und auf fertige und bewährte Objekte zurückzugreifen. :nixweiss: Abgesehen davon ist es für Anfänger vermutlich einfacher zu verstehen, als mit der MemManager-API und Pointerlisten rumzumurksen. ;)

Performance-Technisch sehe ich da keine Unterschiede (wenn es denn anwendbar wäre).

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Gammatester
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 328
Erhaltene Danke: 101



BeitragVerfasst: Do 28.05.09 13:57 
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconGammatester hat folgendes geschrieben Zum zitierten Posting springen:
dann doch ein allerletzen Mal.
Ich geb´ dir mal einen guten Rat für´s Leben: sieh zu, dass du immer steigerungsfähig bleibst. :zwinker:

Jetzt muß es halt das aller-allerletze Mal sein (das ist beliebig iterationsfähig, also bitte keine weiteren guten Ratschläge).

Zitat:
Scheinbar schon: ;)
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
var
    PInt: PInteger;
    Float: Double;
begin
  PInt^ := Float;

Unit1.pas(xx): Inkompatible Typen: 'Integer' und 'Double'


Ich denke, daß Du das bewußt falsch verstehen willst. Ich sehe nirgends ein @. Die diskutierte Situation ist

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var
    Int: Integer;
    Float: Double;
type
  PDouble = ^Double;
begin
  PDouble(@int)^ := Float;