AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

ReportMemoryLeaksOnShutDown

Ein Thema von venice2 · begonnen am 21. Jun 2020 · letzter Beitrag vom 22. Jun 2020
Antwort Antwort
venice2
(Gast)

n/a Beiträge
 
#1

AW: ReportMemoryLeaksOnShutDown

  Alt 21. Jun 2020, 13:37
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.

Result := string(AnsiString(ExportPtr));

Geändert von venice2 (21. Jun 2020 um 13:41 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.733 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: ReportMemoryLeaksOnShutDown

  Alt 21. Jun 2020, 14:45
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.
Thomas Mueller
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
698 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: ReportMemoryLeaksOnShutDown

  Alt 21. Jun 2020, 19:07
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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.550 Beiträge
 
Delphi 12 Athens
 
#4

AW: ReportMemoryLeaksOnShutDown

  Alt 21. Jun 2020, 19:27
Zitat:
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.
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.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (21. Jun 2020 um 19:29 Uhr)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.079 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: ReportMemoryLeaksOnShutDown

  Alt 21. Jun 2020, 22:21
Ihr könntet auch mal ruhig auf die Ursprungsfrage eingehen und mitteilen, dass das setzen von ReportMemory...usw. auf True zwar ganz nett ist, aber sich zum Richtigen FastMM4 wie ein Dreirad zu einem Traktor verhält.

Venice2, nehme dir doch bitte 10 Minuten Zeit und schaue dir an, wie man den FastMM4 extern einbindet und das entstehende Log lesen lernt:
https://youtu.be/o0yZgQoV8MA
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#6

AW: ReportMemoryLeaksOnShutDown

  Alt 21. Jun 2020, 22:25
Ihr könntet auch mal ruhig auf die Ursprungsfrage eingehen und mitteilen, dass das setzen von ReportMemory...usw. auf True zwar ganz nett ist, aber sich zum Richtigen FastMM4 wie ein Dreirad zu einem Traktor verhält.

Venice2, nehme dir doch bitte 10 Minuten Zeit und schaue dir an, wie man den FastMM4 extern einbindet und das entstehende Log lesen lernt:
https://youtu.be/o0yZgQoV8MA
Werde ich tun.
Danke für den Rat.
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#7

AW: ReportMemoryLeaksOnShutDown

  Alt 21. Jun 2020, 23:28
Habe mir das Video angesehen und eingerichtet.
Ändert aber nichts an der Ausgabe ausgenommen das Log ist etwas detaillierter und gibt mir genau das aus was ich schon wusste.

Result := GetExportPtr(Path, Delimiter); // Hier bleibt EurekaLog stehen damit kann ich aber nichts anfangen.

Das wird so auch in das Log geschrieben das in dieser Funktion etwas nicht freigegeben wird.
Was das ist, ist mir ebenfalls bekannt.
Ich alloziere Speicher der nicht freigegeben wird (angeblich).
Ich bekomme hier 14 Speicher Lecks weil ExportPtr 14 mal aufgerufen wird innerhalb einer schleife und die größe des Speichers anhand des Strings strExport neu zugewiesen wird.

ExportPtr := AnsiStrAlloc(Length(strExport) + 1);

ExportPtr

Seltsam ist nur das ich ihn freigebe wenn die DLL beendet wird und zwar in Destroy.

Delphi-Quellcode:
destructor TMyLib.Destroy;
begin
  StrDispose(ExportPtr);
end;
EDIT:
OK. Das ist mein Fehler.
Zitat:
Ich bekomme hier 14 Speicher Lecks weil ExportPtr 14 mal aufgerufen wird innerhalb einer schleife und die größe des Speichers anhand des Strings strExport neu zugewiesen wird.
Ich gebe den String frei.
Aber!
Wenn ich diesen jedesmal innerhalb der Schleife neu Alloziere dann Alloziere ich 14x mal neuen Speicher und der vorherige wird nicht freigegeben.

Ich habe die Zuweisung jetzt aus der Schleife herausgenommen und weise den Speicher erst zu wenn strExport sein Maximum(Length) erreicht hat.
Also einmalig direkt nach der Schleife!

Siehe da die Speicherlecks sind weg.

Geändert von venice2 (22. Jun 2020 um 00:25 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:22 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