ich habe mich mal näher damit beschäftigt wie man Strings sauber an eine
DLL und wieder zurück gibt und habe festgestellt, dass ich damit wohl zu sorglos umgegangen bin wenn ich sie einfach nur als pChar deklariert habe und dann auf beiden Seiten geich wieder in Strings gewandelt habe
Um den String in eine Funktion reinzugeben, ist das absolut unproblematisch, da der Speicher ja erst dann freigegeben wird, nachdem der Programmfluss die Funktion wieder verlassen hat. Beim Rausgeben von Strings aus einer Funktion an den Aufrufer funktioniert das natürlich nicht.
Gibt es andere Möglichkeiten ohne dass ich einen festen Bereich reserviere
Nicht wirklich. Wenn du dieses Modell implementieren willst, dann würde ich für den ersten Aufruf jeweils schon einen Buffer "auf gut Glück" reservieren. Gegebenenfalls reicht Dieser dann aus und du sparst dir den zweiten Aufruf. Schön ist dieses Design allerdings generell nicht.
Die Windows
API benutzt - wie schon erwähnt - auch gerne dieses Verfahren. Hier kann es aber unter Umständen auch passieren, dass sich die Daten zwischen zwei Aufrufen ändern (z.b. wenn man mit
NtQuerySystemInformation alle laufenden Prozesse oder Threads auflisten will, kann das schnell mal passieren). Hier kommt man dann sogar nicht drumrum die
API in einer Schleife aufzurufen, bis der übergebene Buffer schließlich passt (die Anzahl der Durchläufe kann man natürlich ein wenig optimieren, indem man auf den initial zurückgelieferten Wert nochmal ein paar Kilo-/Byte aufaddiert).
Statt eines einfachen Aufrufs landest du somit bei einer Schleife und mindestens einer zusätzlichen Variable.
Eine Alternative, die mir spontan einfällt, wäre die Verwendung eines
IString
Interfaces, welches z.b. eine Methode
SetString(const S: String)
implementiert. Darin müsstest du dann zwar vermutlich trotzdem manuell einen Speicher erstellen und den String reinkopieren (die Referenzzählung funktioniert bei direkter Zuweisung nicht wirklich über
DLL-Grenzen hinweg; es sei denn man verwendet Laufzeit Packages bzw. SharedMem), aber die Freigabe könnte automatisiert im Destructor erfolgen (der ja bei Interfaces sogar automatisch aufgerufen wird) und deine
DLL-Funktion müsste auch nur einmalig ausgeführt werden.