![]() |
AW: ReportMemoryLeaksOnShutDown
Zitat:
Kann den Original Quelltext leider nicht zeigen. Trotz allem nochmals Danke für den Versuch zu helfen. |
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.
|
AW: ReportMemoryLeaksOnShutDown
Zitat:
Selbst wenn du recht hast was ich dir nicht absprechen will. |
AW: ReportMemoryLeaksOnShutDown
Zitat:
Delphi-Quellcode:
Probier's aus, das Leak wird weg sein.
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; |
AW: ReportMemoryLeaksOnShutDown
Delphi-Quellcode:
ExportPtr ist PAnsiChar und kann so nicht als String zurück gegeben werden.
Result := ExportPtr;
gruss |
AW: ReportMemoryLeaksOnShutDown
Zitat:
Der Compiler erzeugt den notwendigen Code. |
AW: ReportMemoryLeaksOnShutDown
Zitat:
Und ich sehe nur Kauderwelsch nicht wirklich noch irgendetwas mit einem identifizierbaren string zu tun.
Delphi-Quellcode:
Result := string(AnsiString(ExportPtr));
|
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:
Korrekt?
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; 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:
In der DLL wird dann der übergebene Speicherbereich gefüllt:
var
Res: integer; Buffer: Array[0..255] of AnsiChar; s: AnsiString; begin Res := MyDllFunction(@Buffer, SizeOf(Buffer)); s := PAnsiChar(@Buffer); end;
Delphi-Quellcode:
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.
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; |
AW: ReportMemoryLeaksOnShutDown
Ich habe auch schon Windows-API Funktionen gesehen, die dann ihre Freigabe-Routine mitgeben. Man macht das im Aufruf dann so :
Code:
Wie Du siehst, Die DLL stellt dir 2 Funktionen zur Verfügung, da sie den Speicher alloziert und deswegen auch wieder freigeben muss.
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; 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. |
AW: ReportMemoryLeaksOnShutDown
Zitat:
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:
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.
GetProcaddress(Lib, 'WTSEnumerateSessionsW');
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:31 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