![]() |
TRTTIMethod.Invoke eines Interface ausführen
Hallo,
bei Versuch einen Serializer zu schreiben, bleibe ich gerade bei den Interfaces stecken. Der Serializer ist eine rekursive Funktion die ein TValue entgegen nimmt. Übernommen aus diesem Thread: ![]() Allerding ist der Interface Teil in dem sonst gut funktionierenden Beispiel leer. Das habe ich folgend ergänzt. Es wird über alle Methoden die das Interface definiert iteriert und wenn eine Methode einen Rückgabewert <> nil (also Funktion) hat und keine Parameter erwartet, wird versucht die rekursive Funktion erneut aufzurufen mit dem Rückgabewert der aufzurufenden Funktion:
Code:
Dass ich hier bei "LMethod.Invoke(thing,.." eine AV bekomme ist nicht weiter verwunderlich, denn ich übergebe statt einer Instanz nur ein Interface.
tkInterface: // Identifies an interface type.
begin sList.Add(FSumIndent + 'interface ' + name + ':' + thing.TypeInfo.name); IncIndent(); for LMethod in LContext.GetType(thing.TypeInfo).GetMethods do begin if (LMethod.ReturnType <> nil) and (length(LMethod.GetParameters) = 0) then Serialize(LMethod.name, LMethod.Invoke(thing, []), sList); //<-- AV end; DecIndent(); sList.Add(FSumIndent + 'end'); end; Aber die Frage ist wie komme ich an das Objekt ran, dass hinter dem Interface steckt? |
AW: TRTTIMethod.Invoke eines Interface ausführen
Wo genau tritt der Fehler auf?
* wirklich beim Ausführen der Interface-Methode * oder erst im Serialize Bei welcher Methode knallt es? Zitat:
weil sonst geschieht es dir zu Recht, wenn es knallt. :angle: Und auch sonst keine gute Idee, einfach so blind irgendwas aufzurufen, wenn man nicht weiß was es macht. * da könnte auch drin ein
Delphi-Quellcode:
oder
format c:
Delphi-Quellcode:
gemacht werden
delete the internet
* oder es wird ein Objekt/Interface zurückgegeben, welches du nicht wieder freigibst (Speicherleck) oder vielleicht doch (peng, wenn es garnicht freigegeben werden darf) * oder etwas ala Lock/Unlock, z.B. für eine CriticalSection (Deadlock oder schlimmer) * oder Zitat:
Delphi-Quellcode:
funktioniert seit ein paar wenigen Jahren, aber ausschließlich für Interfaces, wo auch ein Delphi-Objekt drin steckt.
thing as TObject
|
AW: TRTTIMethod.Invoke eines Interface ausführen
Du solltest dieses Interface mit as oder per hartem Cast z.B. auf TObject casten können. Bei mir funktioniert der Code so allerdings. Wie sehen denn dein Interface, die Klasse dazu und der Aufruf des Serializers aus?
Mein Test:
Delphi-Quellcode:
{$M+}
IBlub = interface ['{E9AB3CA6-9F88-4D30-9D9D-57D7A0821810}'] function GetTest: string; end; TBlub = class(TInterfacedObject, IBlub) published function GetTest: string; end; |
AW: TRTTIMethod.Invoke eines Interface ausführen
Zitat:
Das erstaunlich ist, das es jetzt funktioniert..und zwar ohne Änderungen :o Neuer Tag neues Glück kann man da wohl sagen. Es wird daran gelegen haben, dass in den gestrigen Versuchsobjekten ein Interface auf ein nicht mehr existierendes Object referenziert hat (was ich fälschlich ausgeschlossen hatte). :roll: Danke euch für die Unterstützung |
AW: TRTTIMethod.Invoke eines Interface ausführen
OK, wenn es NUR "Eigenes" ist,
aber ALLE Interfaces implementieren 3 Funktionen für die Speicherverwaltung, und Zwei davon treffen auf deine Bedingungen zu. (hat Result und keine Parameter)
Delphi-Quellcode:
IInterface = interface
['{00000000-0000-0000-C000-000000000046}'] function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; end; Zitat:
denn Interfaces räumen sich selbst auf, wenn keine Variable mehr auf sie zeigt. OK "eigentlich" ... auch viele TComponent implementieren Interfaces, aber dort mit deaktivierter Referenzzählung (_AddRef und _Release machen nichts), also dort hat nicht das Interface die Controlle, sondern die VCL und solche Interface-Zeiger können wirklich ins Nirvana zeigen. (drum sollte man an dieser Stelle das Interface nur kurz nutzen) PS: Unter Anderem dafür gibt es das [unsafe]. ![]() ![]() Abgesehn von so Dingen wie bei TComponent, sollte man es möglichst vermeiden gleichzeitig Interface- und Objekt-Referenzen zu haben. So gibt es auch keine potentiellen Streitigkeiten, wer das Objekt aufräumt. |
AW: TRTTIMethod.Invoke eines Interface ausführen
Zitat:
Der Serializer, bzw. TRTTIType.GetMethods liest nur die Methoden die explizit in einem folgend deklarierten Interface definiert sind:
Delphi-Quellcode:
IMyInterface = interface(IInterface)
function MyFunc1: interger; function MyFunc2: interger; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:12 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