Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Rückgabe von PWideChars in DLL-Funktionen (https://www.delphipraxis.net/207320-rueckgabe-von-pwidechars-dll-funktionen.html)

TurboMagic 12. Mär 2021 11:16

Rückgabe von PWideChars in DLL-Funktionen
 
Hallo,

mal angenommen ich habe einen Record der so definiert ist:

Delphi-Quellcode:
TMyReturnRec = packed record
  Str1, Str2: PWideChar;
end;
In einer Funktion die den als Rückgabewert besitzt kopiere ich die Inhalte von Delphi Strings rein:

Delphi-Quellcode:
var
  MyStr1, MyStr2: string;

function GetData: TMyReturnRec;
begin
  GetMem(result.Str1, (Length(MyStr1) * SizeOf(WideChar)) + 1);
  result := StringToWideChar(MyStr1, result.Str1, Length(MyStr1) + 1);
end;
Jetzt holt sich der Aufrufer diesen Record ab.
Nur: wer sollte wann den Speicher freigeben?
Wenn der AUfrufer ein Delphi Programm ist, welches meine Import Bibliothek benutzt,
kopiert er diese WideCHars gleich wieder in Delphi Strings und gibt mittels FreeMem
den Speicher frei:

FreeMem(MyReturnRec.Str1, Length(MyReturnRec.Str1) + 1);

Nur: wenn der Aufrufer der DLL nicht Delphi benutzt?
Soll der "verpflichtet" weden sowas ähnliches wie dieses FreeMem aufzurufen?

markus888 12. Mär 2021 18:12

AW: Rückgabe von PWideChars in DLL-Funktionen
 
Zitat:

Zitat von TurboMagic (Beitrag 1484975)
Soll der "verpflichtet" weden sowas ähnliches wie dieses FreeMem aufzurufen?

Die Empfehlung lautet, dass der Aufrufende, einen Buffer übergibt in den die dll die Daten reinkopiert.
Dann ist das klar geregelt.

Es geht aber auch anders.
In OleAut32.dll gibt es jede Menge Funktionen die eine Referenz für einen BSTR Pointer erwarten.
Den String und die Adresse des Pointers erzeugt dann die dll.
Für die Freigabe ist dann logischerweise der Empfänger verantwortlich.

himitsu 12. Mär 2021 18:43

AW: Rückgabe von PWideChars in DLL-Funktionen
 
Bei BSTR kannst im DelphiCode einfach WideString verwenden, denn der kapselt einfach nur diese APIs.

Joar, wie überall.
* du erstellst es, also gibst du frei
* eine Funktion exportieren zum Abholen
* und noch ein Export für die Freigabe-Funktion

Oder wie wäre es mit einem Interface mit BString/WideString?

TurboMagic 13. Mär 2021 10:58

AW: Rückgabe von PWideChars in DLL-Funktionen
 
Naja, ich hab' mich halt gefragt was passiert,
wenn jemand eine Nicht Delphi Anwendung schreibt welche die DLL nutzt.

Diese PWideCHars die ich zurückgebe sind Momentan ja Kopien von Delphi strings
(mittels GetMem und Move).

Was wäre und wie würde das funktionieren, wenn ich die nicht als Kopie
zurückgebe sondern direkt auf den Delphi string zeigen lasse?

Klar, dann sind die nur solange gültig wie meine strings in meiner Liste
gespeichert bleiben, aber der Aufrufer müsste sich nicht um das Freigeben
köümmern und sollte halt selber eine Kopie anfertigen.

Einziger, hier aber zu verschmerzender, Nachteil wäre, dass er den Inhalt
der strings in meiner Liste verpfuschen kann.

Hach wie schön wäre das, wenn damals C gleich einen "gescheiten" string
Datentyp bekommen hätte...

himitsu 13. Mär 2021 12:30

AW: Rückgabe von PWideChars in DLL-Funktionen
 
Jupp, wie gesagt, PWideChar,
* entweder das ist ReadOnly dann ist der Andere dir egal ... DU mußt nur dafür sorgen, dass der Zeiger lange genug gültig ist
* oder der wer speicher erstellt, der gibt auch frei
* * der Nutzer erstellt und du schreibst nur den Inhalt ... der Nutzer gibt frei wann er will
* * oder du erstellst den Speicher, in deinem Speichermanafer, dann mußt du auch freigeben ... der Nutzer ruft dein Free auf
* * oder du nutzt einen globalen Speicher ala GlobalAlloc, VirtualAlloc oder eben den WinAPI vom BSTR

In Delphi WideString und Andere nutzen auch Klassen dafür, oder sie nutzen direkt die WinAPI MSDN-Library durchsuchenSysAllocString und ihre Freunde.
Kannst in Delphi auch die API nutzen, aber der WideString macht einfach alles automatisch, inkl. AutoCasts von/in andere String-Typen. Und mit automatischem SysFreeString. (nur das SysReleaseString/SysAddRefString hat Borland/Codegear/Embarcadero noch nicht geschaft ... wurde ja auch erst mit XP erfunden)

TurboMagic 13. Mär 2021 13:09

AW: Rückgabe von PWideChars in DLL-Funktionen
 
Naja, die DLL soll so angelegt sein, dass diese evtl. später auch für nicht Windows Plattformen compilierbar ist...
Damit fallen BSTR tec. raus.
Das deutet aber alles darauf hin, dass ich den PWideChar wohl irgendwie auf meinen internen String zeigen
lassen muss, da diese solange gültig sind bis entweder die DLL entladen wird oder jemand die Funktion
aufruf, welche die Liste mit Inhalten füllt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:16 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