Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Speicherfreigabe in Delphi DLL (Aufruf aus Java) (https://www.delphipraxis.net/143128-speicherfreigabe-delphi-dll-aufruf-aus-java.html)

mjustin 10. Nov 2009 10:15


Speicherfreigabe in Delphi DLL (Aufruf aus Java)
 
Hallo,

im Netz beziehen sich sehr viele Artikel zum Thema DLL und Delphi auf den Aufruf der DLLs aus Delphi - nun suche ich Tipps und best practices für den umgekehrten Fall: die DLL wird in Delphi erstellt und soll aus anderen Programmen (konkret Java) aufgerufen werden.

Wie sieht es aus mit Speicherfreigabe z.B. für PChar und Byte Arrays, die an das aufrufende Programme übergeben werden, welche Seite ist dafür zuständig? Kann man Speicherlecks innerhalb der DLL zuverlässig aufspüren, z.B. mit FastMM4? Eventuell hat jemand einen Link auf einen kurzen Artikel für diesen Fall.

Zur Zeit arbeite ich an einer kleinen Dokumentation zum Thema Java / Delphi Kommunikation über Java Native Access (JNA) - es funktioniert bisher problemlos, aber ich schreibe normalerweise keine DLLs und kenne die typischen Fallstricke nicht. Ich poste nachher noch ein paar Sourcecodebeispiele...

himitsu 10. Nov 2009 10:21

Re: Speicherfreigabe in Delphi DLL (Aufruf aus Java)
 
Es ist einfach immer derjenige für die Freigabe des Speicher zuständig, welcher diesen auch reserviert hat.

Wenn jetzt die Delphi-DLL speicher reserviert und diesen an Java abgibt, dann erstellt man einfach eine GibSpeicherFrei-Prozedur und exportiert diese.
Dann kann das Java den Pointer an Delphi übergeben und dieses gibt dann den Speicher wieder frei.

Zitat:

Zitat von mjustin
Kann man Speicherlecks innerhalb der DLL zuverlässig aufspüren, z.B. mit FastMM4?

joar

du brauchst in der DLL einfach nur FastMM einbinden (fals es nicht schon in Delphi drinnen ist) und dann die Speicherüberwachung aktivieren ... genauso wie in einer EXE

xaromz 10. Nov 2009 10:27

Re: Speicherfreigabe in Delphi DLL (Aufruf aus Java)
 
Hallo,
Zitat:

Zitat von himitsu
Wenn jetzt die Delphi-DLL speicher reserviert und diesen an Java abgibt, dann erstellt man einfach eine GibSpeicherFrei-Prozedur und exportiert diese.
Dann kann das Java den Pointer an Delphi übergeben und dieses gibt dann den Speicher wieder frei.

wobei ich anmerken möchte, dass es üblich ist, dass der Host Speicher reserviert und der DLL zur Verfügung stellt. Dadurch spart man sich den Aufruf einer expliziten Speicherfreigabe über die DLL. Nachteil ist, dass man vorher die DLL fragen muss, wie viel Speicher die entsprechende Funktion braucht. Wenn das vorher nicht klar ist, funktioniert dieser Weg natürlich nicht.

Gruß
xaromz

mjustin 10. Nov 2009 10:31

Re: Speicherfreigabe in Delphi DLL (Aufruf aus Java)
 
Zitat:

Zitat von himitsu
Es ist einfach immer derjenige für die Freigabe des Speicher zuständig, welcher diesen auch reserviert hat.

wie funktioniert es bei DLL-Aufrufen von Funktionen der Windows API, z.B. in Windows.pas wird eine kernel32 Funktion so deklariert:

Delphi-Quellcode:
function lstrcpy(lpString1, lpString2: PChar): PChar; stdcall;
Es wird ein neuer String als PChar zurückgegeben an das aufrufende Delphi Programm, vermutlich wurde in der Windows DLL der Speicher reserviert. Wie erfährt Windows, dass der String nicht mehr benutzt wird, und es ihn freigeben kann? Ich weiss, das ist sicher eine der typischen Anfängerfragen :)

himitsu 10. Nov 2009 10:50

Re: Speicherfreigabe in Delphi DLL (Aufruf aus Java)
 
Nein, bei MSDN-Library durchsuchenlstrcpy mußt du den Speicher vorher reservieren und diese Funktion kopiert dann den String in diesen Speicher.

praktisch kannst du hier schön bei der WinAPI abgucken, denn da ist es meistens so:

- Programm reserviert Speicher
- Funktion kopiert Daten in diesen Speicher
- Programm kümmert sich um die Freigabe des Speichers

Ab und zu kommt es auch mal vor, daß die WinAPI den Speicher reserviert und dann eine weitere Funktion für die Freigabe anbietet.

mjustin 10. Nov 2009 11:05

Re: Speicherfreigabe in Delphi DLL (Aufruf aus Java)
 
Zitat:

Zitat von himitsu
Nein, bei MSDN-Library durchsuchenlstrcpy mußt du den Speicher vorher reservieren und diese Funktion kopiert dann den String in diesen Speicher.

Danke für den Link - alles ist nun etwas klarer geworden :idea:

Viele Grüße,

mjustin 15. Nov 2009 09:22

Re: Speicherfreigabe in Delphi DLL (Aufruf aus Java)
 
Zitat:

Zitat von himitsu
Es ist einfach immer derjenige für die Freigabe des Speicher zuständig, welcher diesen auch reserviert hat.

Wenn jetzt die Delphi-DLL speicher reserviert und diesen an Java abgibt, dann erstellt man einfach eine GibSpeicherFrei-Prozedur und exportiert diese.

Ok, also zum Beispiel so (frei nach http://www.codexterity.com/memmgr.htm)

Delphi-Quellcode:
function Echo(const Arg: PChar): PChar; stdcall;
var
  Tmp: string;
begin
  Tmp := Arg + ' Echo';
  Result := StrAlloc(Length(Tmp));
  StrCopy(Result, PChar(Tmp));
end;

procedure FreeEcho(Arg: PChar);
begin
  StrDispose(Arg);
end;
Die zweite Möglichkeit (Aufrufer fragt DLL zuerst wieviel Speicher reserviert werden soll) schaue ich mir dann noch an...

himitsu 15. Nov 2009 12:29

Re: Speicherfreigabe in Delphi DLL (Aufruf aus Java)
 
Es gibt noch eine dritte Möglichkeit.

Es ist festgelegt, wieviel Zeichen maximal zurückgegeben werden.

Aufrufer stellt einen Puffer für die maximale Größe bereit, läßt sich den Inhalt denn rainkopieren und schaut danach nach, wieviel tatsächlich drinnen ist.

also im Result, oder durch Messen oder ein Stoppzeichen (z.B. bei PChar's) oder in dem Rückgabewert steckt ein Record, wo die Größe mit drinnsteht.

und die 4. ist der 2. ähnlich, nur daß es da keine Extra Funktion für die vorherige Längenabfrage gibt, sonder man einfach einen zukleinen oder keinen (NIL) Puffer übergibt und sich in der Fehlerauswertung die Länge mitteilen läßt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:28 Uhr.

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