Einzelnen Beitrag anzeigen

jensw_2000
(Gast)

n/a Beiträge
 
#1

Dispose = Exception, kein Dispose = Memory Leak

  Alt 20. Sep 2007, 12:05
Die Themen Callback und Pointer auf Records wurden hier ja schön öfter diskutiert.
Ich habe das Prinzip aber offensichtlich immer noch nicht ganz verstanden.

Folgendes Problem:

Ich fordere in der aufrufenden Prozedur mit new(PointerAufRecord) Speicher an und übergebe diesen Pointer an die empfangende Routine.
Dort muss ich den Speicher doch mit Dispose (PointerAufRecord) wieder freigeben, dachte ich ...

Dieses Prinzip verwende ich zum Datenaustausch zwischen einer Clientapplikation und einer DLL, die als API für Drittanbieter dienen soll.

Irgendwie klappt es mit dem Dispose nicht so, wie ich es gerne hätte.

Wenn ich aus der Client-Applikation eine DLL Funktion (z.B. Register_ClientApplication(aRecordTRecord) ) aufrufe, und dort den Speicher von TRecord mit Dispose freigebe, dann gibt es eine Exception beim Beenden des Programmes.

Wenn ich nach diesem Prinzip Daten in die Gegenrichtung (DLL > Clientanwendung) via Callback Funktion transportiere und den Speicher in der Client-Anwendung mit Dispose freigenen möchte, dann gibt es eine Exception beim Aufruf von Dispose.

Lasse ich das Dispose in der DLL und in der Anwendung weg, dann "läuft alles super". Wäre da nicht das "kleine" Problem, dass der Speicher nicht freigegeben wird ....

Ich habe ein kleines Spielprojekt angehängt.
Werft ihr bitte mal einen Blick drauf ?


Aufruf
Delphi-Quellcode:
procedure Register_API( const Servername:String );
begin
  ApiRegisterInfoRec := new(PTApiRegisterInfoRec);
  // Record füllen
  ApiRegisterInfoRec.Servername    := Servername;
  // Callback Prozeduren übergeben
  ApiRegisterInfoRec.OnState    := @OnGetApiState;
  ApiRegisterInfoRec.OnError := @OnGetApiError;
  
  // DLL Register_ClientApplication aufrufen
  Register_ClientApplication(ApiRegisterInfoRec);
  // DLL räumt den Speichern von ApiInitRec
end;
DLL Funktion
Delphi-Quellcode:
function Register_ClientApplication ( aApiRegisterInfo : PTApiRegisterInfoRec):bool; stdcall;
begin
  try
    // Callback Funktionen initialisieren
    @Callback_OnState          := @aApiRegisterInfo.OnState;
    @Callback_OnError          := @aApiRegisterInfo.OnError;

    // Infos aus ApiRegisterInfo übernehmen
    PipeServername                := aApiRegisterInfo.Servername;

    // Speicher von aApiRegisterInfo räumen
    // Dispose geht nicht. Exception beim Beenden der Client-Applikation
    // Dispose(aApiRegisterInfo);

    Registered := true;
  except
    on e:exception do
    begin
      registered := false;
      if assigned(Callback_OnError) then
        OnSendError(1001,esClientAPI,e.Message);
      raise exception.create('Fatal: Register_ClientApplication'+#13#10+e.Message);
    end;
  end;
  result := registered;

  // mit aktuellem Status antworten
  OnSendState(registered, true,101, PipeServername);
end;
Angehängte Dateien
Dateityp: zip spielprojekt_dll__callback_und_records_149.zip (923,8 KB, 0x aufgerufen)
  Mit Zitat antworten Zitat