Autor |
Beitrag |
synogen
Hält's aus hier
Beiträge: 5
WinXP Pro
D7 Prof
|
Verfasst: Do 25.11.04 16:08
mein problem besteht darin, dass ich mehrere records habe die alle ungefähr so aufgebaut sind:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| type daten = record d1:string[50]; d2:string[70]; d3:string[10], end; |
diese records will ich nun ausgeben, aber vorher will ich überprüfen ob der record leer ist (also ob keines der string felder einen wert enthält).
diese überprüfung will ich aber in eine funktion machen, welche für alle records funktioniert (zumindest alle die nur strings enthalten), d.h. die funktion muss im stande sein unabhängig vom typ zu erkennen ob der record leer ist oder nicht.
meine gedanken dazu sind folgendermaßen:
1. ich übergebe den record an die funktion als pointer (damit es mit allen record typen klappt)
2. ich erstelle einen zweiten record vom selben typ wie der übergebene, und leere ihn mit FillChar, dann erstelle ich einen pointer auf diesen record
3. ich vergleiche die beiden record-pointer mit hilfe von CompareMem
da dies leider auch nach mehrstündigem probieren wenig erfolg brachte wollte ich fragen ob vielleicht schon mal jemand so etwas, oder so etwas ähnliches gemacht hat und weiß, wie das gehen könnte, danke im vorraus!
|
|
st-matze
      
Beiträge: 138
Win 3.11, Win 95, Win 98, Win XP
D7 Ent, D6 Pers, (D5 Pers)
|
Verfasst: Do 25.11.04 16:27
Das liegt an dem Aufbau der Arrays und dem aussehen im speicher:
Einleeres Array, also mit '' - strings vom typ den du angegeben hast sieht im Speicher ungefähr so aus:
Quelltext 1:
| 00A3040103430000007E00100149005A000100000001000000050000005254D377A3040103FCF512000000000004841400000200000400000004000000470000001500000013000000048414000F001200030000000700000070001001280861002500000004841400000200000300000003000000250000000200000077324000FC954200 |
und da ist klar, dass es nicht mit mit 00 - bytes übereinstimmt....
Lösung hab ich zwar noch nicht, schaue aber mal ob mir noch was einfällt
|
|
st-matze
      
Beiträge: 138
Win 3.11, Win 95, Win 98, Win XP
D7 Ent, D6 Pers, (D5 Pers)
|
Verfasst: Do 25.11.04 16:35
du müsstest bei der initialisierung der variablen und vor jeder zuweisung den Berich des strings mit 00-bytes fluten, dann klappts mit dem vergleich.
wenn man einem string des records einen kürzeren zuweist als der der vorher drin stand, dann setzt delphi im speicher einen zähler für diesen string runter und ändert im speicher nur die bytes die es betrifft. die im string gelöschten zeichen bleiben im speicher stehen, da delphi sie aufgrund des zählers nicht beachtet. dieser datenmüll verhindert deinen vergleich.
|
|
st-matze
      
Beiträge: 138
Win 3.11, Win 95, Win 98, Win XP
D7 Ent, D6 Pers, (D5 Pers)
|
Verfasst: Do 25.11.04 16:40
|
|
st-matze
      
Beiträge: 138
Win 3.11, Win 95, Win 98, Win XP
D7 Ent, D6 Pers, (D5 Pers)
|
Verfasst: Do 25.11.04 16:43
Vielleicht hilft dir ansonsten folgende Funktion:
Sie gibt dir den Speicherinhalt als Hexstring aus. Hilft vielleicht bei der analyse, wenn man weiss, was man eigentlich vergleicht.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| type Trec = record d1: string [50]; d2: string [70]; d3: string [10]; end; var myrec: trec;
function getbytes(IN_P:Pointer; IN_Size: integer):string; var i: integer; c: Pchar; begin c:=PChar(IN_P); Result:=''; for i:= 0 to IN_Size-1 do begin Result:=Result+inttohex(Ord(c[i]),2); end; end;
procedure TForm1.Button1Click(Sender: TObject); begin Memo1.Text:=getbytes(@myrec,sizeof(myrec)); end; |
|
|
synogen 
Hält's aus hier
Beiträge: 5
WinXP Pro
D7 Prof
|
Verfasst: Do 25.11.04 18:15
erstmal vielen dank für die viele und ausführliche hilfe
der vergleich der beiden records funktioniert ja, mein problem ist eigentlich nur das in eine funktion zu packen, die in etwa so aussehen würde:
typdefinition
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| type daten = record d1:string[50]; d2:string[70]; d3:string[10]; end; |
funktion:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| function RecIsEmpty (rec:daten;typesize:integer):boolean; var emptyrec:daten;
begin FillChar (emptyrec,SizeOf (emptyrec),0); result:=CompareMem (@rec,@emptyrec,typesize); end; |
dies funktioniert (oder sollte zumindest) für den typ "daten", aber nicht für andere datentypen, ich müsste also irgendwie den typ dynamisch machen, so das es beispielsweise so aussieht
Delphi-Quelltext 1: 2: 3:
| function RecIsEmpty (var rec;typesize:integer):boolean; var emptyrec:<variabler datentyp hier>; |
so dass der typ der "rec" und "emptyrec" variable erst zur laufzeit dynamisch gesetzt wird, und dynamische (zur laufzeit) variablentypen lassen nur pointer und variants zu, oder irre ich mich da?
ps: das mit fillchar vor den zuweisungen mach ich bereits 
|
|
st-matze
      
Beiträge: 138
Win 3.11, Win 95, Win 98, Win XP
D7 Ent, D6 Pers, (D5 Pers)
|
Verfasst: Fr 26.11.04 09:32
|
|
synogen 
Hält's aus hier
Beiträge: 5
WinXP Pro
D7 Prof
|
Verfasst: Fr 26.11.04 09:54
supi
hat prima funktioniert, alle felder des records werden verglichen, vielen dank nochmal für die hilfe 
|
|
Motzi
      
Beiträge: 2931
XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
|
Verfasst: Fr 26.11.04 12:27
Hm.. da ging wohl bei der Umstellung mein Beitrag gestern verloren.. naja, hier nochmal.. nachdem du ja die Typesize mitgibst isses eigentlich ganz simpel:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| function RecIsEmpty (pRec: Pointer; dwTypeSize: DWord): Boolean; var p: PChar; begin Result := True; p := pRec; while Result and ((DWord(p) - dwTypeSize) <= DWord(pRec)) do begin Result := p^ = #0; Inc(p); end; end; |
So sparst du dir irgendeinen Speicher zu reservieren, diesen mit Nullen zu füllen und anschließend wieder freizugeben..!
_________________ gringo pussy cats - eef i see you i will pull your tail out by eets roots!
|
|
synogen 
Hält's aus hier
Beiträge: 5
WinXP Pro
D7 Prof
|
Verfasst: Fr 26.11.04 13:51
leider hab ich den quellcode bei meiner praktikumsstelle, kanns also nicht ausprobieren momentan, aber ich verstehe wie du es meinst und das es praktischer ist als speicherreservierung etc.
ich werds gleich montag einbauen
danke vielmals
|
|
|