DLL laden/entladen



  • Hallo zusammen

    Martin Richter schrieb:

    Welche anderen DLLs werden durch diese DLL geladen und wieder entladen?

    Es werden explizit keine anderen DLLs per Code von mir geladen. Was ich im Ereignissprotokoll sehe, ist das eine DLL MSIMG32.dll geladen wird, welche laut Google von MS kommt und etwas mit GDI zu tun hat.

    leck! schrieb:

    behebe erstmal das speicherleck. vielleicht bringts ja was.

    Von welchem Speicherleck redest Du?
    Wenn Du die Sache mit cFileName meinst, die ist schon lange erledigt.

    Meine neusten Erkenntnise sehen jedoch nun so aus, daß wenn ich im Linker die Verwendung der dynamischen RTL einstelle, das Problem behoben ist.
    Allerdings möchte ich die RTL nicht dynamisch verwenden, sondern statisch.

    Meiner Meinung nach ist dies dann ja nun doch ein Builder Problem, oder nicht?
    Wenn ihr dies genauso seht, bitte wieder zurück verschieben. Danke.

    Habe als weiteren Test eine neue DLL mit einer leeren Funktion erstellt und diese exportiert.
    Anschließend eine neue Anwendung welche mit einem Button die DLL dynamisch lädt (LoadLibrary) und wieder entläd (FreeLibrary).
    Wenn ich den Button nun mehrfach drücke sehe ich das der Speicherverbrauch wieder ansteigt.
    Sobald ich auf dynamische RTL umstelle funktioniert es wie es soll. Habe auch schon versucht wie angegeben MEMMGR.LIB mit zu linken. Jedoch ohne Veränderung.

    Bin momentan sehr ratlos.

    MfG Stephan



  • RTL?



  • Hallo Martin

    Martin Richter schrieb:

    RTL?

    Sorry, für alle nicht Builderanwender, hier geht es um die Laufzeitbibliotheken, deshalb auch die Vermutung, daß es sich hierbei um ein builderspezifische Problem handelt.
    Die Laufzeitbibliothek kann entweder dynamisch oder statisch gelinkt werden. Wobei, meiner Meinung nach, die meisten Builderanwender die statische Variante bervorzugen.

    MfG Stephan



  • Und Du bist sicher, dass der DllMain Entry Point stimmt, so dass der Builder seinen Init/Uninit durchführen kann.

    Wennm man in einem MS Produkt, den Entry-Point der DLL selbst verbiegt unddie CRT umgeht, gibt es auch Leaks, wenn man dann doch die CRT benutzt!



  • Hallo Martin

    Das der Entry Point stimmt bin ich mir eigentlich sicher, da der Builder den Code automatisch erstellt, und ich hier nichts geändert habe.
    Mit der CRT meinst Du die Runtime Library, oder?

    Kann der Beitrag wieder zurück ins Builder Forum verschoben werden, oder ist dies Technisch nicht möglich?

    MfG Stephan



  • Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum WinAPI in das Forum VCL (C++ Builder) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Ja mit CRT meine ich die C Runtime Library.

    Ich habe den Beitrag verschoben! Viel Glück bei der weiteren Suche.



  • Hallo zusammen

    @Martin Richter
    Vielen dank für dein Hilfe, und ich glaube Glück kann ich gebrauchen 😉

    Also ich bin wieder da mit meinem Problem, denn so wie es aussieht, hat es etwas mit dem Builder.

    Nochmals eine kurze Zusammenfassung:
    Sobald ich eine DLL (erstellt mit CG2009 und statischer RTL) dynamisch in einem Projekt (CG2009) lade und wieder entlade (mehrfach) steigt der Speicherverbrauch immer weiter an. Nach jedem entladen bleiben ca. 1,2 MB übrig.
    Habe DLL und Anwendung schon mit MEMMGR.LIB sowie ohne erstellt, jedoch ohne Erfolg.
    Wenn die DLL mit dynamischer RTL erstellt wird, funktioniert alles wie es soll.

    Kann dies jemand erklären, bzw bei sich nachvollziehen?

    Bin langsam mehr als ratlos.

    MfG Stephan



  • //---------------------------------------------------------------------------
    //   Wichtiger Hinweis zur DLL-Speicherverwaltung, falls die DLL die statische
    //   Version der Laufzeitbibliothek (RTL) verwendet:
    //
    //   Wenn die DLL Funktionen exportiert, die String-Objekte (oder Strukturen/
    //   Klassen, die verschachtelte Strings enthalten) als Parameter oder Funktionsergebnisse übergibt,
    //   muß die Bibliothek MEMMGR.LIB im DLL-Projekt und anderen Projekten,
    //   die die DLL verwenden, vorhanden sein. Sie benötigen MEMMGR.LIB auch dann,
    //   wenn andere Projekte, die die DLL verwenden, new- oder delete-Operationen
    //   auf Klassen anwenden, die nicht von TObject abgeleitet sind und die aus der DLL exportiert
    //   werden. Durch das Hinzufügen von MEMMGR.LIB wird die DLL und deren aufrufende EXEs
    //   angewiesen, BORLNDMM.DLL als Speicherverwaltung zu benutzen. In diesem Fall
    //   sollte die Datei BORLNDMM.DLL zusammen mit der DLL weitergegeben werden.
    //
    //   Um die Verwendung von BORLNDMM.DLL, zu vermeiden, sollten String-Informationen als "char *" oder
    //   ShortString-Parameter weitergegeben werden.
    //
    //   Falls die DLL die dynamische Version der RTL verwendet, müssen Sie
    //   MEMMGR.LIB nicht explizit angeben.
    //---------------------------------------------------------------------------
    

    Das steht bei jedem neuem DLL Projekt dabei, das man mit BCB6 erstellt. Hast du dich daran gehalten? Da du ja die statische Version der RTL verwenden möchtest.

    mfg



  • Hallo zusammen

    RTL schrieb:

    Das steht bei jedem neuem DLL Projekt dabei, das man mit BCB6 erstellt. Hast du dich daran gehalten? Da du ja die statische Version der RTL verwenden möchtest.mfg

    Stephan schrieb:

    Habe DLL und Anwendung schon mit MEMMGR.LIB sowie ohne erstellt, jedoch ohne Erfolg.

    Wie ich bereits schon mehrfach geschrieben habe, habe ich es mit der MEMMGR.LIB versucht sowie ohne.

    Außerdem ist mir nicht ganz klar ob diese Einschränkung nur dann gilt, wenn ich Klassen bzw VCL Datentypen exportiere.
    Die bisherige DLL, welche ich nun zum Testen dieses Problems verwende, hat nur eine exportierte Funktion, ohne VCL Datentypen, und es wird keine Funktion aufgerufen, sondern die DLL nur geladen und entladen.

    MfG Stephan



  • Hallo zusammen

    Habe unter http://support.codegear.com/article/38487#knownproblems folgenden Hinweis gefunden.

    Dynamische Link-RTL kann beim dynamischen Laden einer DLL nicht verwendet werden

    Wenn Sie eine DLL dynamisch laden, können Sie sie nicht dynamisch mit der Laufzeitbibliothek linken. Ansonsten tritt eine Zugriffsverletzung bei Programmende auf. Deaktivieren Sie zur Lösung des Problems die Option Dynamische RTL auf der Seite Linker des Dialogfeldes Projektoptionen.

    Das heißt doch, daß genau der Fall, welcher bei mir funktioniert (DLL dynamisch laden, RTL dynamisch linken) einen Fehler verursachen soll. Oder habe ich dies falsch verstanden?

    MfG Stephan



  • Mal 'ne generelle Frage: Warum ist es sinnvoll DLLs dynamisch mehrmals zu laden und zu entladen?



  • Stephan schrieb:

    Das heißt doch, daß genau der Fall, welcher bei mir funktioniert (DLL dynamisch laden, RTL dynamisch linken) einen Fehler verursachen soll. Oder habe ich dies falsch verstanden?

    Meinem Verständnis zufolge tritt das Problem nur auf, wenn die DLL die dynamische RTL benutzt. Allerdings sollte das nichts mit den entstehenden Speicherlecks zu tun haben.

    In den Embarcadero-Newsgroups gab es hier mal eine Diskussion über ein Speicherleck beim dynamischen Laden von DLLs in Delphi. Allerdings betraf es C++Builder nicht, da die C++-RTL ihren eigenen Startup-Code hat. Ob weitere Speicherlecks in der dynamischen RTL vorliegen, müßte ich einmal nachmessen, aber die 1.2 MB, die du erwähnst, klingen recht gewaltig (obiges Speicherleck in der Delphi-RTL verursachte nur ein paar KB)...

    Edit: Beim nochmaligen Durchlesen meiner damaligen Analyse fiel mir der folgende Satz auf:

    Ich schrieb:

    With the dynamic RTL enabled (which is broken anyway, according to the product's readme), C++ DLLs leak a lot of memory, but it doesn't seem to be related: it happens in C++Builder 2006 as well, and it occurs irrespective of DisableThreadLibraryCalls().

    Nun scheint das bei dir aber doch nur aufzutreten, wenn du die dynamische RTL nicht benutzt 😕

    Ich bin diesbezüglich nun etwas verwirrt, und wenn ich nächstens Zeit finde, werde ich das einmal eingehender analysieren.



  • Hallo zusammen

    knivil schrieb:

    Mal 'ne generelle Frage: Warum ist es sinnvoll DLLs dynamisch mehrmals zu laden und zu entladen?

    Über Sinn und Unsinn läßt sich hierbei scherlich streiten. Aus verschiedenen Gründen (QuickFix) war ich gezwungen eine Funktion in die besagte DLL auszulagern. Und dann war es einfacher bei jedem Funktionsaufruf die DLL zu laden. Ich weiß, daß dies keine schöne Lösung ist, allerdings geht es mir momentan bei dem Problem mehr um das Prinzip, denn ein Workaround ist ja vorhanden und bereits in besagtem Programm implementiert.

    @audacia
    Es "freut" mich wenn nicht nur ich verwirrt bin, denn ich habe an mir schon gezweifelt ;-))
    Ich werde nochmals ein kleines Testprojekt aufbauen um dem Fehler nachzugehen.
    Jedoch was mir noch nicht ganz klar ist, wann denn nun die memmgr.lib verwendet werden muß?
    Ich verstehe dies so:

    +---------------+--------------+------------------------------------+-------------------------------------+----------------------+
    | RTL dynamisch | RTL statisch | Funktionsexport mit VCL Datentypen | Funktionsexport ohne VCL Datentypen | memmgr.lib verwenden |
    +===============+==============+====================================+=====================================+======================+
    | ja            | nein         | beliebig                           | beliebig                            | nein                 |
    +---------------+--------------+------------------------------------+-------------------------------------+----------------------+
    | nein          | ja           | nein                               | ja                                  | nein                 |
    +---------------+--------------+------------------------------------+-------------------------------------+----------------------+
    | nein          | ja           | ja                                 | beliebig                            | ja                   |
    +---------------+--------------+------------------------------------+-------------------------------------+----------------------+
    

    Also es würde mich freuen wenn du dieses Problem auch nachvollziehen könntest.
    Vielen dank im voraus.
    MfG Stephan


Anmelden zum Antworten