Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   ReportMemoryLeaksOnShutDown (https://www.delphipraxis.net/204717-reportmemoryleaksonshutdown.html)

venice2 21. Jun 2020 12:58

AW: ReportMemoryLeaksOnShutDown
 
Zitat:

Zitat von MyRealName (Beitrag 1467925)
Vielleicht solltest Du mal allen relevanten Code zeigen. Was ich hier sehe ist nur ein Schnipsel aus der DLL (vermute ich) und ein StrDispose, wo nirgends gesagt wird, wann und unter welchen Umständen etwas freigegeben wird.
Die Fehlermeldung zeigt mehrere Speicherlecks, nicht nur eins.

Mehrere aber immer in der gleichen Funktion (angeblich) man wird nicht schlau draus weil man mit solchen Informationen einfach nichts anfangen kann.
Kann den Original Quelltext leider nicht zeigen.
Trotz allem nochmals Danke für den Versuch zu helfen.

dummzeuch 21. Jun 2020 13:07

AW: ReportMemoryLeaksOnShutDown
 
OK, also hatte ich recht und das Leak kann einfach geschlossen werden, indem man die Funktion eien String zurückliefern lässt und den PAnsiChar noch in der Funktion frei gbit.

venice2 21. Jun 2020 13:08

AW: ReportMemoryLeaksOnShutDown
 
Zitat:

Zitat von dummzeuch (Beitrag 1467928)
OK, also hatte ich recht und das Leak kann einfach geschlossen werden, indem man die Funktion eien String zurückliefern lässt und den PAnsiChar noch in der Funktion frei gbit.

Nochmal! Ich kann keinen string zurückgeben die DLL kann auch mit anderen Developer Sprachen verwendet werden.
Selbst wenn du recht hast was ich dir nicht absprechen will.

dummzeuch 21. Jun 2020 13:23

AW: ReportMemoryLeaksOnShutDown
 
Zitat:

Zitat von venice2 (Beitrag 1467929)
Zitat:

Zitat von dummzeuch (Beitrag 1467928)
OK, also hatte ich recht und das Leak kann einfach geschlossen werden, indem man die Funktion eien String zurückliefern lässt und den PAnsiChar noch in der Funktion frei gibt.

Nochmal! Ich kann keinen string zurückgeben die DLL kann auch mit anderen Developer Sprachen verwendet werden.
Selbst wenn du recht hast was ich dir nicht absprechen will.

Ich rede nicht davon, einen String aus der DLL zurückzuliefern, das kann weiterhin ein PAnsiChar sein, sondern aus der Funktion, die die DLL aufuft.

Delphi-Quellcode:
function GetExportPtr(Path, Delimiter): string;
var
  strExport: string;
begin

  // [...]
  ExportPtr := AnsiStrAlloc(Length(strExport) + 1);
  CopyMemory(ExportPtr, PAnsiChar(AnsiString(strExport)), Length(strExport) + 1);
  Result := ExportPtr;
  StrDispose(ExportPtr);
end;
Probier's aus, das Leak wird weg sein.

venice2 21. Jun 2020 13:32

AW: ReportMemoryLeaksOnShutDown
 
Delphi-Quellcode:
Result := ExportPtr;
ExportPtr ist PAnsiChar und kann so nicht als String zurück gegeben werden.

gruss

dummzeuch 21. Jun 2020 13:35

AW: ReportMemoryLeaksOnShutDown
 
Zitat:

Zitat von venice2 (Beitrag 1467935)
Delphi-Quellcode:
Result := ExportPtr;
ExportPtr ist PAnsiChar und kann so nicht als String zurück gegeben werden.

Ausprobiert? Es geht.

Der Compiler erzeugt den notwendigen Code.

venice2 21. Jun 2020 13:37

AW: ReportMemoryLeaksOnShutDown
 
Zitat:

Zitat von dummzeuch (Beitrag 1467936)
Zitat:

Zitat von venice2 (Beitrag 1467935)
Delphi-Quellcode:
Result := ExportPtr;
ExportPtr ist PAnsiChar und kann so nicht als String zurück gegeben werden.

Ausprobiert? Es geht.

Der Compiler erzeugt den notwendigen Code.

[DCC Warning] W1057 Implicit string cast from 'AnsiChar' to 'string'
Und ich sehe nur Kauderwelsch nicht wirklich noch irgendetwas mit einem identifizierbaren string zu tun.

Delphi-Quellcode:
Result := string(AnsiString(ExportPtr));

dummzeuch 21. Jun 2020 14:45

AW: ReportMemoryLeaksOnShutDown
 
Stopp, ich muss mich entschuldigen, ich habe Blödsinn geschrieben, weil ich was falsch verstanden hatte.

Du hast eine DLL, die Du in Delphi schreibst und die diese Funktion exportiert:

Delphi-Quellcode:
function GetExportPtr(Path, Delimiter): PAnsiChar;
var
  strExport: string;
begin

  // [...]
  ExportPtr := AnsiStrAlloc(Length(strExport) + 1);
  CopyMemory(ExportPtr, PAnsiChar(AnsiString(strExport)), Length(strExport) + 1);
  Result := ExportPtr;
end;
Korrekt?

Und diese Funktion soll nicht nur von Delphi aus sondern auch aus anderen Programmiersprachen heraus aufgerufen werden können.

(Irgendwas stimmt da nicht, die Parameter haben keinen Typ.)

Prinzipiell ist es bei der Übergabe von Strings an DLLs so, dass man sich entscheiden muss, wer den Speicher alloziert und wer ihn frei gibt. Üblicherweise macht das der Aufrufer:

Delphi-Quellcode:
var
  Res: integer;
  Buffer: Array[0..255] of AnsiChar;
  s: AnsiString;
begin
  Res := MyDllFunction(@Buffer, SizeOf(Buffer));
  s := PAnsiChar(@Buffer);
end;
In der DLL wird dann der übergebene Speicherbereich gefüllt:

Delphi-Quellcode:
function MyDllFunction(_Buffer: PAnsiChar): integer; stdcall;
var
  s: string;
  as: AnsiString;
begin
  s := IrgendwasDasDenStringLiefert;
  as := s;
  StrCopy(PAnsiChar(as[1]), _Buffer);
  Result := Length(as);
end;
Die Alternative wäre, dass die DLL eine Funktion exportieren muss, die Speicher frei gibt. An die übergibt man dann den aus der DLL zurückgelieferten PAnsiChar zur Freigabe. Das ist aber in der Regel zu aufwändig.

MyRealName 21. Jun 2020 19:07

AW: ReportMemoryLeaksOnShutDown
 
Ich habe auch schon Windows-API Funktionen gesehen, die dann ihre Freigabe-Routine mitgeben. Man macht das im Aufruf dann so :

Code:
const
  CurrentServerHandle = 0;
  WTSEnumerateSessions : TWTSAPI32_WTSEnumerateSessions = NIL;
  WTSFreeMemory : TWTSAPI32_WTSFreeMemory = NIL;

procedure ShowSessions;
var
  Count : DWord;
  pSessionInfo : pTWtsSessionInfo;
begin
  Lib := LoadLibrary('WTSAPI32.DLL');
  @WTSEnumerateSessions := GetProcaddress(Lib, pChar('WTSEnumerateSessionsW'));
  @WTSFreeMemory := GetProcaddress(Lib, pChar('WTSFreeMemory'));
  if WTSEnumerateSessions(CurrentServerHandle, 0, 1, pSessionInfo, Count) then
  begin
    // DoSometing
  end;
  WTSFreeMemory(pSessionInfo);
end;
Wie Du siehst, Die DLL stellt dir 2 Funktionen zur Verfügung, da sie den Speicher alloziert und deswegen auch wieder freigeben muss.
Ist es eine fixe Länge kannst Du auch den schon allozierten Speicher als Parameter übergeben und auf Deiner Seite dann auch wieder freigeben (was dummzeuch ja auch schon geschrieben hatte).
Was du NICHT machen kannst ist Speicher in der DLL allozieren und beim Aufrufer in der Exe freigeben, weil das unterschiedliche MemoryManager sind.

himitsu 21. Jun 2020 19:27

AW: ReportMemoryLeaksOnShutDown
 
Zitat:

Delphi-Quellcode:
PAnsiChar(as[1])

Einen AnsiChar (ordinaler Typ) in einen PChar zu casten, wenn das nicht schief läuft.

PS: Bei Übergabe einer "echten" Konstante (nicht typisiert) an PChar, kann man den Cast weglassen, und Delphi sich den richtigen Typ aussuchen lassen.
Delphi-Quellcode:
GetProcaddress(Lib, 'WTSEnumerateSessionsW');
Wobei ich selbst keine LoadLibrary/GetProcAddress mehr verwende, sondern entweder statische Links oder die statischen über Delayed-Loading, wenn es sich um APIs handelt, die es nicht immer gibt, oder es DLLs sind, die nicht beim Start direkt geladen werden sollen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:40 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz