DLL-Heap-Problem



  • Hallo Leute,

    hier geht es um das eigentlich alt bekannte Problem, dass DLL und Applikation jeweils ihren eigenen Heap haben und die Applikation keinen Speicher der DLL freigeben darf und umgekehrt.
    Ich habe einen SIO-Treiber, als eigenständiger Thread, ausgelagert in eine DLL, der Daten von der seriellen Schnittstelle liest und über eine Callback-Funktion an die Applikation liefert.
    In der Applikation existiert eine Art Stream-Puffer, der die Daten aufsammelt und analysiert. Die genannte Callback-Funktion ruft die Put-Methode des Streams auf und schiebt die Daten somit in den Stream. Soweit alles ok.
    Merkt die Put-Methode, dass dem Stream-Puffer nun der Speicher ausgeht, allokiert sie automatisch einen größeren Puffer, kopiert die alten Daten hinein und löscht den alten Puffer. Und dabei krachts jetzt!
    Da die Put-Methode von der Callback-Funktion aus gerufen wurde, welche wiederum aus der DLL heraus gerufen wurde, geschieht das Put offensichtlich im Kontext der DLL und nicht in dem der Applikation (ist das wirklich so???). Das Freigeben des bereits zu Beginn im Kontext der Applikation angelegten Puffers der Stream-Klasse geht schief (Debug-Version bringt HEAP-Fehlermeldung, Release bringt Absturz mit 'Senden an MS').

    Hat jemand für dieses Problem bereits eine Lösung bzw. einen halbwegs einfachen Workaround?

    Ich habe schon probiert den Stream zu Beginn keinen Puffer allokieren zu lassen (Kontext der APP) um beim ersten Put-Aufruf den Puffer im Kontext der DLL anzulegen. Doch dabei tritt ein anderer merkwüdiger Fehler auf. Es erscheint die HEAP-Fehlermeldung, dass Speicher modifiziert wurde, der bereits freigegeben ist. Es sieht so aus als zeigt der Zeiger irgendwo in den Heap der DLL (was ja so sein soll), doch wenn der Kontext wieder auf die Applikation umgeschalten wird, zeigt er in den Heap der App, wo er natürlich irgendwo! drauf zeigt.
    Kann ich evtl. vor dem new-Aufruf festlegen in welchem Kontext der Speicher erstellt werden soll?
    Bei der zweiten Variante hab ich ja auch das Problem, dass der Stream-Puffer seinen Speicher beim Beenden der App freigeben soll, dies aber nun wieder im Kontext der App geschieht und der Stream einen Zeiger in den DLL-Heap hält. Diesen Speicher darf er ja aber nicht freigeben...

    schonmal Danke
    D.E.N



  • mir würe spontan shared memory einfallen http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/using_shared_memory_in_a_dynamic_link_library.asp

    allerdings finde ich die benutzung einer dll für so einen fall nicht einleuchtend.



  • keine Peilung, was du machen möchtest, aber ich kann dir trotzdem nen Tipp geben.
    Speichere irgendwo ab, wer den Speicher alloziert hat und lasse dann je nachdem, die DLL bzw. die EXE den Speicher freigeben, sollte funktionieren.

    Wie funktioniert das eigentlich? Woher weiß malloc z.B., das es der DLL aufgerufen wird?

    MfG
    DDR-RAM



  • das passiert oft, wenn man zu den dll's (und der exe) die statische runtime library dazulinkt. jeder hat dann seine eigenen heaproutinen (malloc, new, etc), die nichts voneinander wissen. probier's mit der dynamischen (multithreaded) runtime lib. wenn das nix hilft: --> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/memory/base/heapalloc.asp
    oder (allerdings immer 4k blöcke) --> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/memory/base/virtualalloc.asp



  • achso, bin zwar nicht Threadersteller, aber trotzdem Danke 😉



  • Danke an alle. Das Problem lag an einer anderen Stelle in meiner Applikation, hat sich nur an dieser Stelle ausgewirkt. Sorry also nochmal für die Mühe.

    Was ich vermutet hatte trifft doch nicht zu. Es ist also nicht so, dass Speicher, der durch eine Callback (aus einer DLL-heraus in die App) allociert wird, auch im Heap der DLL angelegt wird. Das wär auch irgendwie schlimm, man müßte in jeder Klasse, die selbst Speicher auf dem Heap allociert, beachten, dass der Speicher von einem anderen Modul kommen könnte!

    Es ist aber definitiv so, dass Speicher, der in der DLL allociert wird, z.B. ein Objekt einer String-Klasse in der DLL, nicht im Kontext der Applikation freigegeben werden darf!


Anmelden zum Antworten