![]() |
Delphi-Version: 5
pointer auf Interface als messageparameter
hallo,
ist es möglich einen pointer auf ein interface irgendwie in einen messageparameter zu packen? folgendes konstrukt funktioniert zwar beim umwandeln pinterface --> pointer, aber zurück gibts ne AV
Delphi-Quellcode:
gibt es da irgendeine andere möglichkeit an das interface zu kommen?
type
IPlugIn = interface(IUnknown) ... end; TCustomPlugIn = class(TInterfacedObject, IPlugIn) ... end; PPlugIn = ^IPlugIn PPlugInEvent = ^TPlugInEvent; TPlugInEvent = packed record ... PlugInAddr: LongInt; end; function AsPPlugIn(const PlugIn: IPlugin): Pointer; begin GetMem(result,SizeOf(PPlugIn)); PPlugIn(result) := @PlugIn; end; function AddEvent(...const PlugIn: IPlugIn): integer; begin ... PPlugInEvent(FEventList[result])^.PlugInAddr := LongInt(AsPPlugIn(PlugIn)); // liefert beim Auswerten für PPlugIn(PlugInAddr)^: (TCustomPlugin($Adresse) as IPlugIn) end; // bei einem späteren Aufruf gibts aber ne AV: procedure HoleInterfaceAusEvent(index: integer; out PlugIn); begin PlugIn := PPlugIn(PPlugInEvent(FEventList[index])^.PlugInAddr)^; // hier sieht man bei Ausdruck überwachen nur noch PPlugIn(PPlugInEvent(FEventList[index])^.PlugInAddr)^ = (Pointer($Adresse) as IPlugIn) end; |
AW: pointer auf Interface als messageparameter
Wozu willst du das in einen Pointer casten?
Nimm doch einfach das Interface als Resulttyp. PS: Wenn du wild mit Pointern castest, dann kann es leicht mal passieren, daß due die Referenzzählung "beschädigst". Ein Interface ist ja quasi schon intern ein Zeiger, nur eben mit einer ordentlichen Referenzbehandlung. |
AW: pointer auf Interface als messageparameter
ja das problem ist, dass ich das interface als msg.wparam (msg: TMessage) übergeben möchte, und zwar ohne dabei die referenzzählung zu erhöhen. und irgendwie habe ich das gefühl, dass ein interface nciht nur ein zeiger ist, sondern da auch noch infos über das eigentlich objekt drinnenstehen. ich glaube mal gelesen zu haben, dass ein interface aus dem methodentable des interfaces und nem zugehörigen offset, je nachdem wer das interface gerade implementiert besteht. kann es sein, dass mir deswegen beim speichern der interfacevariable a la pointer := @interface die infos über den offset verloren gehen?
edit: im prinzp soll derjenige der die message bekommt das ganze dann so auswerten können:
Delphi-Quellcode:
soweit ich das verstanden habe, ist ja dann die refernzzählung sowieso ausgehebelt, weil ich das interface als pointer übergebe und delphi da dann nciht mitzählt. ich will halt nur nciht den empfänger der message dafür verantwortlich machen das interface wieder auf nil zu setzen, bis auf das was er selber zuordnet
var Sender: IPlugIn;
begin Sender := PPlugIn(msg.WParam)^; end; |
AW: pointer auf Interface als messageparameter
Kann es sein, dass du den Pointer auf eine lokale Interface-Variable übergibst? Das Interface wird nämlich beim Verlassen der Funktion automatisch zerstört, der Pointer zeigt dann ins nirgendwo.
|
AW: pointer auf Interface als messageparameter
hmmm ich übergeben ihn an das ergebnis der funktion AsPPlugIn...
ahhh mir fällt da was ein, ich übergebe das interface als const-parameter an die funktion AsPPlugIn liegt es daran, dass diese referenz dann nach verlassen der funktion AsPPlugIn wieder gelöscht wird? |
AW: pointer auf Interface als messageparameter
perfekt das wars!
eine frage zum verständnis hab ich noch. ist es möglich, den speicherbereich, auf den eine interfacevariable zeigt, mit move zu kopieren? damit ließe sich das ganze dann doch wieder in funktion packen oder irre ich mich? so nach dem motto:
Delphi-Quellcode:
wobei das jetzt nciht funktioniert
function StoreInterfaceToPointer(const AInt: IInterface): Pointer
begin new(result, SizeOf(AInt)); move(AInt, result, SizeOf(AInt)); end; |
AW: pointer auf Interface als messageparameter
Vereinfacht gesagt sieht die Speicherstruktur so aus:
Code:
@Variable = Pointer auf die Variable auf dem Stack
(@ Steht für einen Pointer)
Stack————————————————>| Heap—————————————————————————————————————————————————————————————————————> Variable: • @ Interface ————————>Interface: • @ Objekt —————————————————>Objekt: • @ Interface-Methode 1 • @ VMT ———————————> Methodentabelle: • @ Interface-Methode 2 • Felder und Co. • @ Objekt-Methode 1 • @ Interface-Methode n • @ Objekt-Methode 2 • @ Objekt-Methode n Pointer(Variable) = Pointer auf Interface auf dem Heap Ersteres ist eine schlechte Idee, da natürlich der Stack sich jederzeit ändert kann. Zweiteres ist auch eine schlechte Idee, da am Ende einer Funktion Delphi automatisch alle lokalen Interfaces freigibt, d.h. es wird erst Variable._Release aufgerufen, wenn der Refcounter 0 ergibt, wird das Objekt freigegeben. Anschließend wird aber IMMER das Interface selbst freigegeben, auch wenn das Objekt nicht zerstört wird. Wenn du also einen Pointer auf ein lokales Interface woanders weiter verwendest, geht das höchstwahrscheinlich in die Hose. |
AW: pointer auf Interface als messageparameter
wow dankeschön. jetzt hab ich mal ein "bild" davon wie interfaces angelegt sind. :)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:18 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