.DLL og memory leak?

Tags:    delphi

Hej alle! Jeg er godt i gang med at rode mig ud i en masse med .dll filer - det går ind til videre fint nok, den virker som den skal. Jeg åbner den som stdcall, og da den indeholder en form, har jeg en OnClose handler der siger

procedure TfrmDllForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
frmDllForm := nil;
end;

(formnavnet er et andet, det her er et eksempel her fra siden).

Det er jo alt sammen meget godt. Men så vidt jeg kan se, er det kun form, der får frigjort sin hukommelse. Fx har jeg en public boolean, der starter som false. Første gang jeg kører .dll filen er den false, og jeg sætter den til true i min kode. Ok, jeg lukker .dll formen, åbner den igen, og den boolean er stadig true!

Der sker åbenbart det, hvad vel virker logisk, at kun formen frigøres. Koden i DPR filen til .dll filen siger

procedure ShowDllForm; stdcall;
begin
if checkcreate = nil then
checkcreate := Tcheckcreate.Create(nil);
checkcreate.Show;
end;

exports
ShowDllForm;

(checkcreate er det, formen/uniten hedder)

Så, når jeg sætter formen til nil, vil jeg gætte på, at den egentlige .dll (den der er lavet af .dpr) ikke bliver frigjort - eller at formen bliver frigjort, men at det unit, den er i (der også har en class jeg selv har skrevet), ikke bliver det.

Jeg har prøvet at kalde release og free på checkcreate, men resultatet er enten, at det ikke gør nogen forskel, eller at der bliver rejst en exception.

Nu kan man selvfølgelig sige, at en boolean memory leak ikke er verdens største katastrofe. Derudover har jeg to DWORD og en string, og det er selvfølgelig heller ikke alverden - det er en relativt lille applikation, .dll filen er til, og jeg gætter på, at hukommelsen til disse variabler bliver frigivet, når hovedapplikationen lukkes ned. Men det ville være meget rart, hvis jeg helt kunne få frigivet hukommelsen fra .dll'en.

Nogen forslag?

Mvh Lilac Soul / Carsten



4 svar postet i denne tråd vises herunder
2 indlæg har modtaget i alt 7 karma
Sorter efter stemmer Sorter efter dato
Hej alle! Jeg er godt i gang med at rode mig ud i en masse med .dll filer - det går ind til videre fint nok, den virker som den skal. Jeg åbner den som stdcall, og da den indeholder en form, har jeg en OnClose handler der siger

procedure TfrmDllForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
frmDllForm := nil;
end;

<snip en masse>


At du sætter frmDllForm til nil betyder ikke at frigører det objekt variablen peger på. Du mister bare referencen til variablen og objektet findes stadig i hukommelsen. For at løse problemet kan du vel lave en destructor, hvor i du rydder pænt op efter dig. Den bør så blive kaldt automatisk efter Action := caFree.



Hej alle! Jeg er godt i gang med at rode mig ud i en masse med .dll filer - det går ind til videre fint nok, den virker som den skal. Jeg åbner den som stdcall, og da den indeholder en form, har jeg en OnClose handler der siger

procedure TfrmDllForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
frmDllForm := nil;
end;

(formnavnet er et andet, det her er et eksempel her fra siden).

Det er jo alt sammen meget godt. Men så vidt jeg kan se, er det kun form, der får frigjort sin hukommelse. Fx har jeg en public boolean, der starter som false. Første gang jeg kører .dll filen er den false, og jeg sætter den til true i min kode. Ok, jeg lukker .dll formen, åbner den igen, og den boolean er stadig true!

Der sker åbenbart det, hvad vel virker logisk, at kun formen frigøres. Koden i DPR filen til .dll filen siger

procedure ShowDllForm; stdcall;
begin
if checkcreate = nil then
checkcreate := Tcheckcreate.Create(nil);
checkcreate.Show;
end;

exports
ShowDllForm;

(checkcreate er det, formen/uniten hedder)

Så, når jeg sætter formen til nil, vil jeg gætte på, at den egentlige .dll (den der er lavet af .dpr) ikke bliver frigjort - eller at formen bliver frigjort, men at det unit, den er i (der også har en class jeg selv har skrevet), ikke bliver det.

Jeg har prøvet at kalde release og free på checkcreate, men resultatet er enten, at det ikke gør nogen forskel, eller at der bliver rejst en exception.

Nu kan man selvfølgelig sige, at en boolean memory leak ikke er verdens største katastrofe. Derudover har jeg to DWORD og en string, og det er selvfølgelig heller ikke alverden - det er en relativt lille applikation, .dll filen er til, og jeg gætter på, at hukommelsen til disse variabler bliver frigivet, når hovedapplikationen lukkes ned. Men det ville være meget rart, hvis jeg helt kunne få frigivet hukommelsen fra .dll'en.

Nogen forslag?

Mvh Lilac Soul / Carsten

Hej Carsten,

Prøv at tilføj (og eksporter) en funktion som kan lukke og deallokere din form:
Fold kodeboks ind/udKode 


Når du skal deallokere og lukke formen kalder du HideDLLForm.

/Michael.




I sredet for at saette din frmDllForm til nil, kan du saa ikke bare frigpre den frmDllForm.Free? Derved bliver den destrueret og alle varianter og komponenter der er assignet til den vil ogssaa blive frigjort fra hukommelsen.





Prøv at tilføj (og eksporter) en funktion som kan lukke og deallokere din form:
Fold kodeboks ind/udKode 


Når du skal deallokere og lukke formen kalder du HideDLLForm.

/Michael.

He, sjovt, det er lige præcis hvad jeg endte med at gøre :) Tak for hjælpen alle sammen, jeg sætter stor pris på det.



t