![]() |
Wie einer Function einen 'Datentyp' übergeben??
Hi Leute
Ich zerbreche mir gerade den Kopf darüber wie ich einer Function einen zufälligen Typ zuweisen kann. Mal zur Übersicht.
Delphi-Quellcode:
function Datentypgrösse(unbekannter_Datentyp):Integer; // kann ein Record integer usw. sein var rl:integer; begin rl:=0; rl:=sizeof(unbekannter_Datentyp); //könnten ja alle möglichen Typen sein result:=rl ; end; Das Problem ist, ich weiß nicht was für ein Datentyp auftauchen wird, also kann ich ihn auch nicht vorher bei der Procedurendefinition bestimmen. Für Denkansätze wäre ich sehr dankbar. |
Re: Wie einer Function einen 'Datentyp' übergeben??
Hallo,
solange du in Records denkst wird das nix. Du solltest in Objekten und Interfaces denken. Ich würde Dein Problem wie folgt lösen: Ich würde als Parameter ein Interface verwenden.
Delphi-Quellcode:
IMyInterface würde dann wie folgt aussehen
function Datentypgrösse(unbekannter_Datentyp : IMyInterface ):Integer; // kann ein Record integer usw. sein
var rl:integer; begin rl:=0; rl:=unbekannter_Datentyp.Size; //könnten ja alle möglichen Typen sein result:=rl ; end;
Delphi-Quellcode:
Jetzt kannst Du jedes Objekt dass das IMyInterface implementiert als Parameter übergeben.
IMyInterface = Interface
['{06C033D1-76E2-452E-8F94-C4ED1DCA429F}'] function Size : Integer; end; Schau Dir folgenden Code mal etwas genauer an:
Delphi-Quellcode:
TMyObject = class(TInterfacedObject, IMyInterface)
public function Size : Integer; end; TMyListObject = class(TListBox,IMyInterface) public function Size : Integer; end; TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } function DataSize(aInterface : IMyInterface) : Integer; public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} { TForm1 } { TMyObject } function TMyObject.Size: Integer; begin Result:=0; end; procedure TForm1.Button1Click(Sender: TObject); var aObject : TMyObject; aListObject : TMyListObject; begin aObject:=TMyObject.Create; DataSize(aObject); // Hier wird ein Objekt des Types TMyObject übergeben aObject.Free; aListObject:=TMyListObject.Create(Nil); DataSize(aListObject); // Hier wird ein Objekt des Types TMyListObject übergeben (eigentlich eine TListBox aListObject.Free; end; function TForm1.DataSize(aInterface: IMyInterface): Integer; begin Result:=aInterface.Size; end; { TMyListObject } function TMyListObject.Size: Integer; begin Result:=0; end; Ab D2005 würde ich die Möglichkeiten der ClassHelpers ausloten. (Habe bislang aber nur etwas darüber gelesen) |
Re: Wie einer Function einen 'Datentyp' übergeben??
Hi.
Das Beispiel ist etwas irritierend, da es ja genau zu diesem Zweck in Delphi die System-Funktion SizeOf() gibt. Ansonsten braucht es dazu Informationen, die dem Compiler zur Übersetzungszeit vorliegen. Grüße vom marabu |
Re: Wie einer Function einen 'Datentyp' übergeben??
Zitat:
Man könnte auch für jeden nur erdenklichen Typen eine überladene Methode bereistellen :freak: P.S. In meinem Beispiel ist Result:=0 in den Size Methoden nur als Platzhalter zu sehen. Size muss natürlich typspezifisch implementiert werden. |
Re: Wie einer Function einen 'Datentyp' übergeben??
Hallo Jens,
Zitat:
Freundliche Grüße vom marabu |
Re: Wie einer Function einen 'Datentyp' übergeben??
Wow, das mit Interface ist für mich Neuland.
Aber scheint eine effektive Methode zu sein.
Delphi-Quellcode:
Was bedeutet das??
IMyInterface = Interface
['{06C033D1-76E2-452E-8F94-C4ED1DCA429F}'] Zitat:
Ich habe auch schon darüber nachgedacht das mit Pointer zu lösen. Oder ist das ne dumme Idee. Marabu, das mit den sizeof war nur ein Beispiel. Ich programmiere gerade eine Empfangsroutine für meine eigenen ServerSockets- und Clientsockets- Kompo. Ich möchte es dem User es so einfach wie möglich machen. Grundidee dazu ist, das Server und Client gleiche Typen hin und her schicken können, die voher vom Benutzer definiert wurden. Aufgabe der Sende und Empfangsroutine soll sein diese Typen zu füllen bzw zu senden. |
Re: Wie einer Function einen 'Datentyp' übergeben??
Eine elegante Lösung des Problems.
Allerdings eben mit Pointern.
Delphi-Quellcode:
Exportdaten ist Typenlos und ich kann es einen definierten Typen zuweisen.Function Konvertiere_Datenpaket(var Daten:Pointer;var ExportDaten;Datensize:int64):boolean; begin if (Daten=nil)or(Sizeof(Daten^)<0) then exit; Move(Daten^,ExportDaten, Datensize); //konvertiert untypirisierte Typen in Typerisierte Typen end; Und funktioniert bestens. |
Re: Wie einer Function einen 'Datentyp' übergeben??
Hab nur ich Probleme mit dem letzten Code?
SizeOf kann nicht kleiner als 0 sein ... sogar Delphi hat was dagegen :shock: Zitat:
Also Sizeof(Daten^) < 0 0 < 0 False [add] Ach ja, Datensize = Int64 :shock: MOVE möchte da gern 'nen Integer ... wir sind noch nicht im 64-Bit Zeitalter :zwinker: Und da Move intern selber nochmal prüft, ob die übergebenen Pointer NIL sind, ist demnach die If-Abfrage
Delphi-Quellcode:
ebenfall unnötig.
if Daten = nil then exit;
Demnach ist ein
Delphi-Quellcode:
, ohne eine Funktion drumrum, völlig ausreichend. (jedenfalls bei dem obrigen Beispiel)
Move(Daten, ExportDaten, SizeOf(ExportDaten));
|
Re: Wie einer Function einen 'Datentyp' übergeben??
Naja ich prüfe nicht was im Socket steht, das drück ich der Function auf. Wenn der Wert zb -1.. hat, dann wird die Funktion halt abgebrochen.
Für eine normale Anwendung wäre das natürlich besser.
Delphi-Quellcode:
Function Konvertiere_Datenpaket(var Daten:Pointer;var ExportDaten;Datensize:int64):boolean;
begin Move(Daten,ExportDaten, Datensize); end; |
Re: Wie einer Function einen 'Datentyp' übergeben??
Hallo Jens
Delphi-Quellcode:
IMyInterface = Interface
['{06C033D1-76E2-452E-8F94-C4ED1DCA429F}'] function Size : Integer; end; ['{06C033D1-76E2-452E-8F94-C4ED1DCA429F}'] Du sag mal diese Nummer läßt du sie generieren?? Oder denkst du dir die aus?? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:22 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