Seite 1 von 2

echtes "malloc" in PB (statt "AllocateMemory&

Verfasst: 14.11.2008 11:34
von Rozek
Hallo zusammen!

Ich habe folgendes Problem: ich möchte in PB eine DLL für eine Anwendung schreiben, die von mir erwartet, daß ich Daten (Zeichenketten) in vorher (von mir in der DLL) mittels "malloc" angelegten Speicherbereichen erzeuge und die "Gewalt" über diese Bereiche an die Anwendung abtrete.

Mit anderen Worten: die DLL ruft "malloc", die Anwendung später das zugehörige "free".

Mit "AllocateMemory" kann ich in PB zwar Speicher reservieren, dieser wird aber auch weiterhin von PB verwaltet - insbesondere am Ende der Anwendung von PB automatisch wieder freigegeben.

Weiß jemand einen Ausweg aus diesem Dilemma?

- kann man "malloc" von PB aus irgendwie direkt aufrufen (ohne dazu eine weitere DLL schreiben zu müssen)
- kann man PB dazu bewegen, per "AllocateMemory" angelegte Speicherbereiche zu "vergessen"?

Vielen Dank im Voraus für jede Art von Hilfe!

Verfasst: 14.11.2008 12:00
von NicTheQuick
Jedes Programm gibt automatisch beim Beenden jeden angelegten Speicher wieder frei.
Auch mit malloc. 'AllocateMemory()' von PB macht nichts anderes als malloc auch.
Deswegen kannst du beide Befehle untereinander nutzen.

Verfasst: 14.11.2008 12:13
von Rozek
Danke für die schnelle Antwort!

Aber sie löst (vermutlich) nicht das Problem, nämlich daß die oben erwähnte Anwendung den von der DLL reservierten Speicher vermutlich schon vorher freigegeben hat!

Wenn jetzt die DLL entladen wird, versucht sie bereits längst freigegebenen Speicher erneut freizugeben - sollte es da nicht heftig knallen?

Darüber hinaus müßte sich PB unnötigerweise unzählige angeblich noch reservierte Speicherbereiche merken (von denen es annimmt, daß sie noch freigegeben werden müßten) was bei langen Laufzeiten eine ganze Menge Speicher in Anspruch nehmen dürfte.

Verfasst: 14.11.2008 12:26
von NicTheQuick
Normalerweise sollten die Speicherbereiche einer DLL immer zu denen der Anwendung
gehören, das die DLL geladen und aufgerufen hat.

Aber wenn du dir zu unsicher damit bist, nutz doch einfach die entsprechende API-Funktion GlobalAlloc.

Verfasst: 14.11.2008 13:44
von Rozek
Danke für den Tip, aber...

...ich benötige etwas Plattform-unabhängiges.

Derzeit sehe ich keinen anderen Ausweg, als in C eine Mini-DLL (etc.) zu schreiben, die intern "malloc" aufruft.

Verfasst: 14.11.2008 13:48
von Thorium
Eine Anwendung oder DLL sollte beim entladen nicht selbst den Speicher freigeben. Das übernimmt Windows. Windows gibt automatisch jedweden reservierten Speicher frei, schließt Handles, etc. Von daher ist es gut möglich das die DLL den Speicher garnicht selbst freigibt am Ende.

Verfasst: 14.11.2008 13:56
von Rozek
Hmm,

die PB-Dokumentation (zu "AllocateMemory") besagt aber etwas anderes: kein Hinweis darauf, daß sich "AllocateMemory" in einer DLL anders verhält als in einer Anwendung...

Verfasst: 14.11.2008 14:08
von Thorium
Rozek hat geschrieben: die PB-Dokumentation (zu "AllocateMemory") besagt aber etwas anderes: kein Hinweis darauf, daß sich "AllocateMemory" in einer DLL anders verhält als in einer Anwendung...
Hab ich ja auch nicht geschrieben.

Die Doku besagt folgendes:
Hinweis: Alle reservierten Speicherbereiche werden automatisch freigegeben, wenn das Programm beendet wird.
Das heisst aber nicht zwingend das PB die Speicherbereiche freigibt. Da Windows das sowieso macht, sollte man das auch Windows überlassen und ich nehme mal an das es bei PB auch so ist.

Verfasst: 14.11.2008 15:38
von mk-soft
malloc ist ein 'c' befehl und keine API.

Ein bessere vorgang ist es den Speicher von der Applikation zu erstellung und dann den Zeiger auf den Spiecher zu übergeben.
Ist eine normale vorgehensweise.

Beispiel

Code: Alles auswählen

ProcedureDLL MyFunction(*buffer, len.l)

  If len < $FFFF
    ProcedureReturn #False
  EndIf
  
  PokeS(*buffer, "Hello World")
  
  ProcedureReturn #True
  
EndProcedure


; Applikation

*mem = AllocateMemory($FFFF)

result = MyFunction(*mem, $FFFF)
Debug result
If result
  Debug PeekS(*mem)
EndIf
FF :wink:

Verfasst: 14.11.2008 16:05
von freak
mk-soft hat recht, malloc() macht unter umständen einiges anders als AllocateMemory().

Einfach den Befehl aus der C runtime importieren:

Code: Alles auswählen

ImportC "msvcrt.lib"
  malloc.i(size)
  realloc.i(*ptr, size)
  free(*ptr)
EndImport

*p = malloc(500)
PokeS(*p, "Hallo Welt")
Debug PeekS(*p)
free(*p)