Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi AnsiString mit fester Länge (https://www.delphipraxis.net/128713-ansistring-mit-fester-laenge.html)

GPRSNerd 4. Feb 2009 14:44


AnsiString mit fester Länge
 
Hi,

weiss jemand, wie ich einen AnsiString fester Länge definiere? Also das AnsiString-Pendant zu String[10]?

Versuche ich AnsiString[10] so gibts ne Compiler-Fehlermeldung unter Delphi 2007:
[DCC Fehler] dEXIF.pas(94): E2029 ';' erwartet, aber '[' gefunden

Danke,
Stefan

PS: Ich versuche gerade die dExif-Units von McGuirez so umzuschreiben, dass sie auch unter Delphi 2009 funktionieren.
Hat das vielleicht schon jemand gemacht?

sirius 4. Feb 2009 14:53

Re: AnsiString mit fester Länge
 
Shortstring[10] vielleicht

himitsu 4. Feb 2009 14:57

Re: AnsiString mit fester Länge
 
String[10] ist ein AnsiString ... genauer gesagt ein ShortString mit maximal 10 Zeichen (also 11 Byte).
Dieses sollte sich auch unter D2009 nicht geändert haben.

GPRSNerd 4. Feb 2009 15:06

Re: AnsiString mit fester Länge
 
Danke himitsu für die Bestätigung, ich hatte so etwas von Andreas H. irgendwo gelesen, aber den Artikel nicht mehr gefunden.

GPRSNerd 5. Feb 2009 10:57

Re: AnsiString mit fester Länge
 
Bis auf ein paar hundert Warnungen wegen impliziter String-Umwandlungen läuft die dEXIF-Komponente, soweit ich das testen konnte, auch unter Delphi 2009 im "ANSIModus".

Danke für die Hilfe,
Stefan

himitsu 5. Feb 2009 11:04

Re: AnsiString mit fester Länge
 
du kannst je die impliziten Stringumwandlungen in Explizite ändern, dann gibt's keine Warnungen mehr :angel2:

GPRSNerd 5. Feb 2009 11:09

Re: AnsiString mit fester Länge
 
Ich weiss. Die "bösen Warnungen" wegen potentiellem Datenverlust bei der Konvertierung von String->Ansi habe ich größtenteils so erledigt.
Die meisten übriggebliebenen Warnungen bei Ansi->String kommen wegen Benutzung von Funktionen wie pos, trim floattostr, inttostr etc.

himitsu 5. Feb 2009 11:27

Re: AnsiString mit fester Länge
 
dort kannst ja notfalls die Parameter nach String casten und das Funktionsergenis dann jeweils nach AnsiString oder WideString (jenachdem auf was das Ergebnis zugewiesen wird).

da paßt es sich dann je nach Delphi an :angel2:
Code:
Var A, Ar: AnsiString;
    W, Wr: WideString;
    S, Sr: String;

                              // Ansi-Delphi Unicode-Delphi
Ar := AnsiString(Trim(String(A))); // A>A>A A>W>A also egal
Ar := AnsiString(Trim(String(W))); // [color=#ff0000]W>A>A[/color] [color=#ff0000]W>W>A[/color] gewollter Datenverlust
Ar := AnsiString(Trim(S));         // A>A>A [color=#ff0000]W>W>A[/color] in Ar paßt eh nicht mehr rein
Wr := WideString(Trim(String(A))); // A>W>W A>A>W mehr Platz, als nötig
Wr := WideString(Trim(String(W))); // [color=#ff0000]W>A>W[/color] W>W>W Ansi: selber Schuld ***
Wr := WideString(Trim(S));         // A>A>W A>W>W hat och genug Platz
Sr := Trim(String(A));             // A>A>A A>W>W Platz genug
Sr := Trim(String(W));             // [color=#ff0000]W>A>A[/color] W>W>W Ansi: hätt in Sr eh nich reingepaßt
Sr := Trim(S);                     // A>A>A W>W>W alles egal


*** wer in 'nem Ansi-Delphi einen UnicodeString mit den Ansi-Funktionen bearbeitet,
hat's nich anders verdiehnt :p

Benmik 11. Apr 2009 14:20

Re: AnsiString mit fester Länge
 
Hallo Stefan,

rein zufällig bin ich auch gerade daran, bei der Anpassung eines Projektes von D7 nach D2009. Hast du was dagegen, mir die Früchte dein Umwandlung zukommen zu lassen?
Was ich auch gern mal wüsste, ist, ob es etwas gibt, um EXIF-Daten völlig neu zu erstellen, also in JPG-Dateien, die (noch) keine EXIF-Daten haben.

Gruß

Benmik

GPRSNerd 11. Apr 2009 22:10

Re: AnsiString mit fester Länge
 
Jau, kein Problem. Sind mittlerweile auch ausgiebig unter D2009 getestet und funktionieren problemlos.

Da der Autor der dEXIF-Komponenten sich auch auf mehrfache Mails nicht meldet, hat er bestimmt auch nix dagegen, wenn ich die angepassten Sourcen hier anhänge. :wink:
Mache ich morgen, wenn ich wieder an meinen Server komme.

Benmik 11. Apr 2009 22:16

Re: AnsiString mit fester Länge
 
Prima! Danke!

Benmik

GPRSNerd 12. Apr 2009 10:50

dEXIF 1.03d portiert nach Delphi 2009
 
Liste der Anhänge anzeigen (Anzahl: 1)
Here we go! Angehängt sind die Units dEXIF 1.03d portiert nach Delphi 2009.
Die Portierung ist eine reine Umstellung auf explizite ANSIStrings, Unicode geht nicht!

Falls jemandem noch Probleme auffallen sollten, bitte melden, so dass wir alle davon profitieren können.

Benmik 12. Apr 2009 18:17

Re: AnsiString mit fester Länge
 
Liste der Anhänge anzeigen (Anzahl: 2)
Vielen Dank!
Das bringt mich zu einer Bitte, die hoffentlich nicht zu viel verlangt ist.
Seit Längerem suche ich nach einer Komponente für BrowseFolder, die benutzerfreundlicher ist als das übliche Angebotene.
Jetzt bin ich auf Torry fündig geworden, es ist WDialogEx. Leider braucht man zu dieser Komponente die TNTControls, und hier hakt es. Obwohl die Komponente explizit für D2009 "ausgepreist" ist, und es eine Art Anpassung für D2009 gibt, funktioniert es nicht. Ich habe schon herumgepolkt, aber meine Kenntnisse von Unicode, Widestrings und AnsiStrings reichen nicht. Hat einer von euch vielleicht etwas Nerv und Zeit, sich das anzusehen? Ich brauche ja die ganze Funktionalität von TNT nicht, mir würde eine Abkopplung schon reichen. Wäre schön. Danke schonmal.

Benmik

GPRSNerd 13. Apr 2009 09:10

Re: AnsiString mit fester Länge
 
Benmik, mache aus deiner neuen Frage bitte einen neuen Thread. Thread-Highjacking mag hier keiner.

Benmik 13. Apr 2009 13:23

Re: AnsiString mit fester Länge
 
Tut mir leid, auch wenn ich den Begriff "Thread-Hijacking" deutlich zu hart finde. Da es um Strings und Anpassung an D2009 geht, ist m.E. doch eine ziemlich Nähe zum eigentlichen Threadanliegen gegeben. Der Autor der Komponente hat mir jetzt geantwortet, vielleicht erarbeiten wir da eine Lösung. Danke nochmal für die Bereitstellung deiner Anpassung.

Benmik

jaenicke 13. Apr 2009 14:46

Re: AnsiString mit fester Länge
 
Zitat:

Zitat von Benmik
Seit Längerem suche ich nach einer Komponente für BrowseFolder, die benutzerfreundlicher ist als das übliche Angebotene.
Jetzt bin ich auf Torry fündig geworden, es ist WDialogEx.

Die kann ja nicht viel, ich habe gerade mal eine Version von TFolderBrowser, die mit D2009 funktioniert, hochgeladen:
http://www.delphi-forum.de/viewtopic...=558093#558093
Das sollte so mit Unicode richtig funktionieren, ein Beispiel findest du im ersten Beitrag.

Benmik 14. Apr 2009 23:55

Re: AnsiString mit fester Länge
 
Hm, nachdem ich mich mit Sebastian per PN ausgetauscht habe und vom Autor meiner Lieblingskomponente eine Version erstellt wurde, die ohne die TNTControls auskommt, habe ich das neue, an D2009 angepasste dEXIF zu kompilieren versucht. Es lief aber keineswegs durch, ich musste noch eine Reihe von "string" durch "AnsiString" ersetzen, z.B. bei den Callback-Funktionen. Und auch bei deinem "string[4]" (dEXIF, 2307) vom Startbeitrag meckerte der Compiler, weil dort "Char" statt "AnsiChar" stand.
Hat das alles seine Richtigkeit? Hast du auch die richtigen Units gepostet, oder ist bei mir was verquer?

Benmik

GPRSNerd 20. Apr 2009 12:00

Re: AnsiString mit fester Länge
 
Ich habe die Units gerade nochmal verglichen und es sind definitiv dieselben, die ich gerade unter D2009 benutze! Wie oben erwähnt, gibts noch ein paar Warnungen und Hinweise, die ich nicht umgesetzt habe.
Wenn du diese Warnungen und Hinweise in den Compiler-Optionen als "Error" deklariert hast, stoppt der Compiler da natürlich.
Lass mal ein paar Zeilennummern und die entsprechenden Fehler sehen...

Den einzigen String[4] in dEXIF ist in der folgenden Funktion:

Delphi-Quellcode:
function tEndInd.Put32s(data:Longint):ansistring;
var
  data2:integer;
  buffer:string[4] absolute data2;
  bbuff:ansichar;
begin
  data2 := data;
  if MotorolaOrder then
  begin
    bbuff    := buffer[1];
    buffer[1] := buffer[4];
    buffer[4] := bbuff;
    bbuff    := buffer[2];
    buffer[2] := buffer[3];
    buffer[3] := bbuff;
  end;
  result := buffer;
end;
Wo musstest du den da zusätzlich Char durch AnsiChar ersetzen? Das ist exakt die Datei-Version, die ich gepostet habe!? Ich habe die Datei gerade extra nochmal runtergeladen.

Außerdem wäre es nett, wie oben erwähnt, wenn du die geänderten Units auch uns zur Verfügung stellen würdest.

himitsu 20. Apr 2009 12:12

Re: AnsiString mit fester Länge
 
Delphi-Quellcode:
data2: integer;
buffer: string[4] absolute data2;
Sicher daß diese so stimmt?
String[4] ist 5 Byte groß und somit liegt buffer[4] nicht mehr im Datenbereich von data2.

Außerdem würde so die länge von buffer falsch gesetzt und wäre somit nahezu unberechenbar.
Length(buffer) = Byte(data2)

GPRSNerd 20. Apr 2009 12:26

Re: AnsiString mit fester Länge
 
Die Einwände verstehe ich nicht so ganz!?

Ich habe an der Logik der Original-Funktion nix geändert bis auf die Ersetzung des Rückgabe-Parameters von String auf AnsiString und bbuff von char nach AnsiChar.
Es handelt sich laut Definition der Funktion um die Umwandlung von Unsigned 32bit Integers...

nicodex 20. Apr 2009 12:49

Re: AnsiString mit fester Länge
 
Zitat:

Zitat von GPRSNerd
Ich habe an der Logik der Original-Funktion nix geändert [...]

Was nicht bedeutet, dass der Originalcode fehlerfrei sein muss ;)

Zitat:

Zitat von GPRSNerd
Es handelt sich laut Definition der Funktion um die Umwandlung von Unsigned 32bit Integers...

Es sieht so aus, als ob beabsichtigt wird, einen 4-Byte Integer in ein 4-Byte ACII-(Tag-)String zu konvertiren. Allerdings macht der Code nicht das, was beabsichtigt zu sein scheint (weil string[4] aus 5 Bytes besteht: Buffer[0] ist die Länge und Buffer[1..4] sind die Zeichen).

edit:
Delphi-Quellcode:
type
  TFourCC = record
    case Integer of
      1: (AsAnsi: array [0..3] of AnsiChar);
      4: (AsLong: LongInt);
  end;

function tEndInd.Put32s(AData: LongInt): AnsiString;
var
  FourCC: TFourCC;
begin
  FourCC.AsLong := AData;
  if MotorolaOrder then // SwapLong(AData)
    FourCC.AsLong := (Swap(LoWord(AData)) shl 16) or Swap(HiWord(AData))
  else
    FourCC.AsLong := AData;
  Result := FourCC.AsAnsi;
end;

Benmik 21. Apr 2009 21:59

Re: AnsiString mit fester Länge
 
Es sieht so aus, als hätte ich doch nicht deine, sondern eine alte Unit erwischt, obwohl auch ich das vorher noch einmal geprüft hatte. Ist mir natürlich peinlich, verstehe es aber selbst nicht ganz. Tschuldigung.

wp_xxyyzz 22. Apr 2009 23:12

Re: AnsiString mit fester Länge
 
Hallo Benmik,

nachdem du dich offenbar gut mit dEXIF auskennst:

Um mein Programm, das dEXIF verwendet, auf Speicherlecks zu testen, habe ich heute mal FastMM4 an den Anfang der uses-Liste des Projekts gesetzt und bin über eine Unmenge von Meldungen über Speicher-Lecks gestolpert, die allesamt von dEXIF herrühren. Auch das mit dEXIF mitgelieferte DExView verhält sich ähnlich.

Ist dir das auch schon aufgefallen, bzw. hast du vielleicht einige dieser Speicherlecks schon beseitigt?

Gruß
Werner

wp_xxyyzz 23. Apr 2009 11:01

Re: AnsiString mit fester Länge
 
Seltsam, mit MemCheck werden keine Speickerlecks gefunden. Aber es war mir ohnehin schon aufgefallen, dass FastMM4 immer wieder harmlose Stringoperationen bemängelt hat.

himitsu 23. Apr 2009 11:09

Re: AnsiString mit fester Länge
 
FastMM, MemCheck und Co. können aber auch nicht alle SpeicherLeaks finden ... vorallem fast alle die, welche nicht über den Speichermanager laufen, fallen nicht auf.


hab hier grad irgendwie den Überblick verloren ... wo/welche ist denn nun eigentlich eine aktuelle Version dieser Datei?

[add]
hab auch mal etwas gespielt :angel:
Delphi-Quellcode:
function tEndInd.Put32s(AData: LongInt): AnsiString;
begin
  SetLength(Result, 4);
  if MotorolaOrder then begin
    asm
      mov eax, &AData
      bswap eax
      mov edx, &Result
      mov edx, [edx]
      mov [edx], eax
    end;
  end else PLongInt(@Result[1])^ := aData;
end;

function tEndInd.Put32s(AData: LongInt): AnsiString;
begin
  SetLength(Result, 4);
  if MotorolaOrder then
    PLongInt(@Result[1])^ := SwapLong(AData)
  else PLongInt(@Result[1])^ := aData;
end;
via Pointer-Variable;
Delphi-Quellcode:
function tEndInd.Put32s(AData: LongInt): AnsiString;
var P: PLongInt;
begin
  SetLength(Result, 4);
  P := @Result[1];
  if MotorolaOrder then begin
    asm
      mov eax, &AData
      bswap eax
      mov edx, &P
      mov [edx], eax
    end;
  end else P^ := aData;
end;

function tEndInd.Put32s(AData: LongInt): AnsiString;
var P: PLongInt;
begin
  SetLength(Result, 4);
  P := @Result[1];
  if MotorolaOrder then
    P^ := SwapLong(AData)
  else P^ := aData;
end;

Benmik 29. Apr 2009 13:32

Re: AnsiString mit fester Länge
 
Nachdem ich kein solcher Delphi-Crack bin wie himitsu (danke an die Wertschätzung von wp_xxyyzz, leider nicht ganz berechtigt :wink: ), habe ich nochmal ein bisschen nachgeforscht, und beim Entwicklerforum einen Link auf einen Artikel von Embarcadero gefunden, der für mich etwas Licht ins Dunkel gebracht hat, und vielleicht dem einen oder anderen (der über Google herkommt?) nützlich sein kann. Man kann mich steinigen, aber die Tatsache, dass der Compiler hinter meinem Rücken einen Haufen Verrenkungen treibt (die natürlich als "magic" bezeichnet werden), war mir so unbekannt.

Delphi in a Unicode World Part I
Delphi in a Unicode World Part II
Delphi in a Unicode World Part III

Ich würde himitsu gern fragen, ob man mit seinem Code jetzt tatsächlich den in dEXIF ersetzen kann. Mir kommt es merkwürdig vor, dass in der ganzen Zeit nie eine Fehlfunktion des Codes resultiert oder jedenfalls nicht bemerkt worden sein soll. Leider ist mir der Unterschied zwischen den beiden Varianten nicht klar, und vor allem nicht, warum die Vorschläge jeweils als Doppelwhopper aufgeführt sind (Zeile 1 / Zeile 15, beispielsweise). Für etwas Aufklärung wäre ich dankbar.
(Mit der Dialogkomponente bin ich übrigens sehr zufrieden, leider hat der Autor sie noch nicht bei Torry aktualisiert).

Danke

Benmik

GPRSNerd 1. Mai 2009 08:21

Re: AnsiString mit fester Länge
 
Es ist aber kein Wunder, dass die vermeintlichen Fehler in der Funktion nicht aufgefallen sind! Sie werden nirgendwo benutzt! Die Korrekturen haben also nur einen gewissen akademischen Wert.

BlueStarHH 20. Jul 2009 13:57

Re: dEXIF 1.03d portiert nach Delphi 2009
 
Liste der Anhänge anzeigen (Anzahl: 3)
Zitat:

Zitat von GPRSNerd
Here we go! Angehängt sind die Units dEXIF 1.03d portiert nach Delphi 2009.
Die Portierung ist eine reine Umstellung auf explizite ANSIStrings, Unicode geht nicht!

Falls jemandem noch Probleme auffallen sollten, bitte melden, so dass wir alle davon profitieren können.

Danke für die Portiertung. Leider ist mir ein Fehler aufgefallen, dessen Ursache ich nicht erkenne: Unter Delphi 5 werden zum einem Bild alle vorhandenen Infos zu "Maker Specific Data" ausgegeben. Bei D2009 mit den neuen Units fehlt sehr viel.

So lasse ich die "Maker Specific Data" ausgeben:

Delphi-Quellcode:
if ImgData.HasEXIF and ImgData.ExifObj.msAvailable then
begin
  // verbose data is only available in the trace strings
  ImgData.ExifObj.ResetIterator;
  while ImgData.ExifObj.IterateFoundTags(CustomEXIF, Item) do
    Memo(Item.Desc, Item.Data);
end;
Im Anhang das Originalbild mit den EXIF-Daten und die beide Ausgaben als Bildschirmfoto.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz