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(aRecord

TRecord) ) 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;