![]() |
PostMessage: Objekte "verschicken" führt zu Access Violation
Gute Nacht,
ich steh gerade glaub übelst auf dem Schlauch und hoffe, dass ihr mir helfen könnt. Hintergrund: Ich schreibe gerade eine Logging-Klases in der eine Add-Methode ein Objekt erzeugt, also die Message die geloggt werden soll. Via PostMessage schicke ich dann die Referenz auf das Objekt an verschiedene Module. Hier mal der Auszug, der das Erzeugen und Versenden beinhaltet:
Delphi-Quellcode:
So, nun zum Empfängercode -- hier wird der Pointer dereferenziert (also das "Objekt") in eine Queue gespeichert:
procedure TApLog.Add(const AMessage: String; const ACategory: TApLogCategory);
var OriginalMsg : TApLogMessage; begin OriginalMsg := TApLogMessage.Create(AMessage, ACategory); try SendToModules(OriginalMsg); finally OriginalMsg.Free(); end; end; procedure TApLog.SendToModules(Source: TApLogMessage); var i : Integer; ClonedMsg : TApLogMessage; begin // Clone and send message to each module for i := 0 to FModuleHandles.Count - 1 do begin ClonedMsg := TApLogMessage.Create(Source); PostMessage(FModuleHandles[i], APM_LOG_MESSAGE, Integer(@ClonedMsg), 0); end; end;
Delphi-Quellcode:
Der Pointer wird korrekt verschickt und stellt somit nicht das Problem dar. Allerdings erhalte ich eine Zugriffsverletztung, wenn die Enqueue()-Methode aufgerufen wird. Zudem habe ich mit der Überwachung festgestellt, dass sicher hinter p kein TApLogMessage verbirgt, also als wäre es freigegeben worden. Aber das geschieht nirgends! Ich habe das mind. 5 mal geprüft.
procedure TApLogCustomModule.APMRecieveMessage(var Msg: TMessage);
var p : ^TApLogMessage; begin try p := Pointer(Msg.WParam); FMessageQueue.Enqueue(p^); while (Cardinal(FMessageQueue.Count) > FMaxBufferElements) do FMessageQueue.Dequeue().Free(); finally Msg.Result := 1; end; end; Nun drängt sich mir die Frage auf: Wird Speicher vom Delphi-Speichermanager überschrieben, wenn keine Referenz mehr darauf exisitert? So weit ich weiß, ist das aber doch nicht der Fall?! Anders kann ich mir aber nicht erklären, warum ich sonst die Zugriffsverletztung erhalte. PS: Nein, ich werde und will kein SendMessage verwenden. |
AW: PostMessage: Objekte "verschicken" führt zu Access Violation
Was das Senden angeht: keinen Pointer darauf (doppelt gemoppelt), sondern das Objekt selbst:
Delphi-Quellcode:
PostMessage(FModuleHandles[i], APM_LOG_MESSAGE, Integer(ClonedMsg), 0);
|
AW: PostMessage: Objekte "verschicken" führt zu Access Violation
Hallo,
ausserdem würde ich nicht wParam, sondern lParam benutzen. Oder ist Word seit neuestem 32Bit gross ? Heiko |
AW: PostMessage: Objekte "verschicken" führt zu Access Violation
Was sind das für Module? Befinden sie sich in einem eigenen Prozess?
Dann hat der Empfänger evtl. einfach keinen Zugriff auf den Speicherraum des Senders. |
AW: PostMessage: Objekte "verschicken" führt zu Access Violation
Und natürlich auch den Empfang des Objektes anpassen:
Delphi-Quellcode:
PS.
procedure TApLogCustomModule.APMRecieveMessage(var Msg: TMessage);
var p : TApLogMessage; begin try p := Pointer(Msg.WParam); FMessageQueue.Enqueue(p); while (Cardinal(FMessageQueue.Count) > FMaxBufferElements) do FMessageQueue.Dequeue().Free(); finally Msg.Result := 1; end; end; WParam und LParam sind beide jeweils 32Bit. |
AW: PostMessage: Objekte "verschicken" führt zu Access Violation
Um den Grund nochmal zu nennen:
Du versendest einen Zeiger auf die Variable und nach Beenden der Prozedur ist diese Variable nicht mehr vorhanden. PS: Ein Objektzeiger ist, wie der Name vermuten läßt, intern auch "nur" ein Zeiger, weswegen man ihn auch direkt casten kann. |
AW: PostMessage: Objekte "verschicken" führt zu Access Violation
Versuche es mal mit SendMessage. Da damit die Ausführung direkt durchgeführt wird, sind die lokalen Variablen der aufrufenden Funktion noch vorhanden. Bei PostMessage sind diese meist schon wieder aufgeräumt, da du .Free aufrufst, bevor die Nachricht überhaupt ankam.
Bernhard |
AW: PostMessage: Objekte "verschicken" führt zu Access Violation
Zitat:
Mit records würde das funktionieren, ansonsten darfst du das Objekt nicht freigaben wenn du es noch verwenden willst! Bist du nen GC gewohnt? @himi: Wenn man ein Objekt erzeugt, sollte das aber doch eigentlich auf dem Heap geschehen, also sollte das eigentliche Objekt (sofern man es nicht freigibt) doch auch nach der Funktion vorhanden sein, oder? @hoika: Beide Parameter sind 32 bit groß. Trotz des Namens ;) |
AW: PostMessage: Objekte "verschicken" führt zu Access Violation
Zitat:
|
AW: PostMessage: Objekte "verschicken" führt zu Access Violation
@jfheins
Zitat:
Delphi-Quellcode:
ClonedMsg := TApLogMessage.Create(Source);
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:45 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