![]() |
Delphi-Version: 2006
String-Interna nutzen
Da in Delphi (leider) Vieles versteckt nicht direkt zugänglich ist,
gibt es hier einen kleinen Converter für alle Strings. Man kann damit via Cast auf einige interne Daten fast aller delphieigenen Stringtypen zugreifen (abgesehn vom ShortString, aber da dürfte der Cast eh fehltschlagen, und WideString). Allerdings ist dieses so nur ab Delphi 2006 / Turbo Delphi nutzbar, aber dafür bietet dieser Record einige Zusatzfeatures, welche das Original System.StrRec, in der System-Unit von Delphi, nicht bietet. (vorallem den Cast ohne einrechnen eines Offsets ala System.Skew oder System.rOff) z.B.:
Delphi-Quellcode:
Var S: String; // String, AnsiString oder das neue UnicodeString
MoveMemory(sonstwohin, StrRec(S).Data, StrRec(S).DataSize);
Delphi-Quellcode:
type
// do not use VStrRec directly StrRec = ^VStrRec; VStrRec = packed record private function GetW(Index: Integer): Word; inline; procedure SetW(Index: Integer; Value: Word); inline; function GetL(Index: Integer): LongInt; inline; procedure SetL(Index: Integer; Value: LongInt); inline; public function Assigned: Boolean; inline; {$IF CompilerVersion >= 20.0} property CodePage: Word index -12 read GetW write SetW; property ElemSize: Word index -10 read GetW {write SetW}; {$IFEND} property RefCount: LongInt index -8 read GetL {write SetL}; property Length: LongInt index -4 read GetL {write SetL}; function Data: Pointer; inline; function DataSize: Integer; inline; end; function VStrRec.GetW(Index: Integer): Word; begin if @Self <> nil Then Result := PWord(PAnsiChar(@Self) + Index)^ else Result := 0; end; procedure VStrRec.SetW(Index: Integer; Value: Word); begin if @Self <> nil Then PWord(PAnsiChar(@Self) + Index)^ := Value; end; function VStrRec.GetL(Index: Integer): LongInt; begin if @Self <> nil Then Result := PLongInt(PAnsiChar(@Self) + Index)^ else Result := 0; end; procedure VStrRec.SetL(Index: Integer; Value: LongInt); begin if @Self <> nil Then PLongInt(PAnsiChar(@Self) + Index)^ := Value; end; function VStrRec.Assigned: Boolean; begin Result := @Self <> nil; end; function VStrRec.Data: Pointer; begin Result := @Self; end; function VStrRec.DataSize: Integer; begin Result := Length {$IF CompilerVersion >= 20.0} * ElemSize {$IFEND}; end; |
AW: String-Interna nutzen
Das sollte man imho gerade nicht machen. Internas sind Internas, da sich sich immer ändern können. Die Ausnutzung von Internas hat zum Debakel bei der Umstellung auf Unicode geführt.
"Dummer" Code, der das nicht macht, hatte im Gegensatz durch derart "genial" getuntem Code keine Probleme damit. |
AW: String-Interna nutzen
Wozu soll das gut sein? Oder anders gefragt, wann braucht man das?
|
AW: String-Interna nutzen
Das ist doch eigentlich einer der Vorteile, denn vorallem .DataSize sollte gegen dieses Unicode-"Debakel" helfen. :angel2:
Abgesehn davon enthält dieser Code BorCodEmbas Konventionen für Strings. Und dieses sogenannte Unicode-"Debakel" kam gerade dadurch, daß man sich eben nicht an die Konentionen gehalten hat. Ich hab in einem Projekt ne eigene Stringkonvertierung (ohne TEncoding und Co.) implementiert und da war es schon nötig, wenn ich diese Interna auch ordnungsgemäß setze, vorallem CodePage und die CharSize. |
AW: String-Interna nutzen
Zitat:
Zitat:
|
AW: String-Interna nutzen
Ich find es gut, zu wissen wo ggf. welche Daten stehen.
Zumindestens dem Auslesen zwecks Überprüfung steht dann nichts mehr im Wege. Gruß K-H |
AW: String-Interna nutzen
Mal unabhängig davon, ob man es jetzt benutzen sollte oder nicht, ist es auf jeden Fall ein eleganter Hack :thumb:
|
AW: String-Interna nutzen
Zitat:
|
AW: String-Interna nutzen
Und jetzt versuche mal etwas, welches Viele seit langem nutzen.
Einen AnsiString (selbst mit ShareMem) zwischen DLL und EXE übergreifend zu nutzen ... aber 'ne PreD2009-DLL/EXE wird nicht mit etwas ab D2009 kompatibel sein. |
AW: String-Interna nutzen
[QUOTE=Luckie;1050755.... Aber so bald beim nächsten Modell die Ölwanne wo anders ist oder anders aussieht, sind meine bisherigen Erfahrungen wertlos.[/QUOTE]
Nun ich verstehe eine Angabe wie "Codepage" so wie den Zettel, der im Motorraum angebracht wird "1. Salatölqualität SAE 10W-50 nächster Wechsel bei km Stand 150 000". Die kann ich ignorieren, ist aber manchmal doch ganz hilfreich (wenn sie denn stimmt). Aber auf jeden fall besser zu sagen das "könnte", als mit den Schultern zu zucken und zu sagen "ist flüssig und fettig". Gruß K-H P.S. Bei uns hat ein Dienstleister vor kurzem ein paar Texte in einer DB "zerbröselt" weil er irgendwo mit den falschen Codepages hantiert hat. Darum gefällt mir die Vorstellung ggf. irgendwo nachschauen zu können ungemein! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz