Tun (statisch gelinkt) DLLs verwenden Sie einen anderen Haufen als das Hauptprogramm?
Ich bin neu in der Windows-Programmierung, und ich habe gerade "lost" zwei Stunden Jagd ein bug den jeder scheint sich bewusst: Sie können nicht erstellen Sie ein Objekt auf dem heap in einer DLL und zerstören es in einer anderen DLL (oder das Hauptprogramm).
Ich bin mir fast sicher, dass unter Linux/Unix ist dies NICHT der Fall ist (wenn es ist, bitte sagt es, aber ich bin mir ziemlich sicher, ich hab das Tausende Male ohne Probleme...).
In diesem Punkt habe ich ein paar Fragen:
1) statisch gelinkten DLLs verwenden Sie einen anderen Haufen als das Hauptprogramm?
2) Ist die statisch gelinkte DLL abgebildet in dem gleichen Prozess Raum des main-Programm? (Ich bin ganz sicher, hier ist die Antwort ein großes JA sonst würde es keinen Sinn machen übergabe von Zeigern von einer Funktion im Hauptprogramm an eine Funktion in einer DLL).
Ich spreche plain/reguläre DLL, nicht, COM/ATL-services
EDIT: Von "statisch" meine ich, dass ich nicht mit LoadLibrary die DLL laden, aber ich verknüpfen mit stub-Bibliothek
- Es hängt von den Einstellungen für jedes Modul. In der Regel, wenn zwei Module verwenden Sie die dynamische CRT, dann teilen Sie den heap, da Sie beide haben die gleiche Instanz des CRT geladen. Wenn ein Modul verwendet die statische CRT-dann hat es seinen eigenen Haufen, da hat er seine eigene Instanz des CRT statisch eingebunden.
- Darüber hinaus ist es möglich, für verschiedene Module, um verschiedene Versionen der dynamische (DLL) CRT, und daher verschiedene Haufen.
- So ziemlich jede nicht-triviale DLL erstellen müssen, die Ihren eigenen Haufen, wenn man darüber nachdenkt. Nehmen Sie die OpenAL-Bibliothek als ein Beispiel. Sie können die feed-Daten in ein Puffer-Objekt (lib macht seine eigene Kopie der Daten), einige Parameter einstellen, und die Bibliothek wird sound Abspielen-toll, einfach, perfekte, keine sorgen. Jetzt stellen Sie sich die zwei Programme laden Sie die Bibliothek. Wohin mit den Daten, wem gehört es? In welchem Teil des physischen RAM ist es? Will ich "ein anderes Programm" sehen zu können (oder zu ändern) die Daten auf meinem Programm-heap? Wenn es Leben auf deinem main-Modul heap, den man irgendwie in Schwierigkeiten...
- Er hat zwei verschiedene Haufen, bedeutet nicht, haben 2 verschiedene virtuelle Adressräume... ich denke, dass der zweite Haufen (der DLL) ist noch abgebildet in der Haupt-Prozess-Adressbereich. In deinem Beispiel denke ich, dass die OpenAL verwendet immer noch Ihre Haupt-Speicher verarbeiten, so sollte es keine zufälligen teilen. Ansonsten gibt es etwas, was ich bin wirklich über fehlende DLLs hier 🙂
Du musst angemeldet sein, um einen Kommentar abzugeben.
DLLs /exes müssen, um eine Implementierung von C run-time-Bibliotheken.
Im Fall von C Windows-Runtime-Bibliotheken, haben Sie die option, um anzugeben, ob Sie möchten, um die Verknüpfung zu dem folgenden:
Jeder von Ihnen wird sich zu einem anderen Haufen, und Sie sind nicht berechtigt pass-Adresse erhalten Sie von heap eine Laufzeit-Bibliothek zur anderen.
Nun, es hängt davon ab, welche C-Laufzeit-Bibliothek die DLL, die du redest in Verbindung gebracht wurde. Angenommen, sagen wir, die DLL, die Sie verwenden, wurden mit der statischen C-Laufzeitbibliothek und die Anwendung code (enthält die main-Funktion) verbunden hat, um multi-threaded-C-Laufzeit-DLL, dann, wenn Sie übergeben einen Zeiger auf reservierten Speicher, in die DLL zu deinem main-Programm und versuchen Sie zu befreien, es da oder Umgekehrt, kann es zu undefinierten Verhalten. So, die grundlegende Ursache sind die C-runtime-Bibliotheken. Bitte wählen Sie diese sorgfältig.
Bitte finden Sie mehr info auf der C-Laufzeit-Bibliotheken unterstützt hier & hier
Einem Zitat aus MSDN:
Vorsicht nicht mischen statische und dynamische Versionen der run-time-Bibliotheken. Mit mehr als eine Kopie des run-time-Bibliotheken in einem Prozess können Probleme verursachen, da die statischen Daten in einer Kopie ist nicht zusammen mit den anderen kopieren. Der linker verhindert, dass Sie aus der Verbindung mit sowohl statische als auch dynamische Versionen in einer .exe-Datei, aber Sie können dennoch am Ende mit zwei (oder mehr) Kopien der run-time-Bibliotheken. Zum Beispiel eine dynamic link library verknüpft mit den statischen (nicht DLL) Version der run-time-Bibliotheken können Probleme verursachen, wenn verwendet mit ein .exe-Datei, die verbunden war mit der dynamische (DLL) version der run-time-Bibliotheken. (Sie sollten auch vermeiden, das mischen der debug-und nicht-debug-Versionen der Bibliotheken in einem Prozess.)
Release
) oder die Einführung Bibliothek-spezifische Zuordnung von Funktionen (Beispielpng_free
imlibpng
.)Lassen Sie uns zuerst verstehen, heap-und stack-Windows-OS-wrt unsere Anwendungen/DLLs. Traditionell, das Betriebssystem und die Laufzeit-Bibliotheken verfügen über eine Implementierung des heap.
Ihre DLL-und exe-link, Multithreading statischen CRT-Bibliotheken. Jede DLL-und exe-Datei, die Sie erstellen, hat einen eigenen heap, d.h. _crtheap. Die Zuweisungen und de-Zuweisungen hat zu geschehen, von jeweils heap. Dass eine dynamisch zugewiesene DLL, nicht de-aus zugewiesen ausführbar und Umgekehrt.
Was können Sie tun? Unseren code kompilieren, die in DLL-und exe mit /MD oder /MDd zur Nutzung der Multi-Thread-und DLL-spezifische version der run-time Bibliothek. Also DLL und exe sind im Zusammenhang mit der gleichen C run-time library und damit eine _crtheap. Zuweisungen sind immer gekoppelt mit de-Zuweisungen innerhalb eines einzigen Moduls.
Wenn ich eine Anwendung, die kompiliert als .exe und ich will eine Bibliothek, die ich kann, entweder als statische link-Bibliothek aus .lib-Datei oder dynamisch verknüpfte Bibliothek aus .dll Datei.
Jedes verknüpfte Modul (ie. jeder .exe-oder .dll) verknüpft werden, um eine Implementierung der C-oder C++ - mal ausführen. Die Laufzeiten selbst eine Bibliothek statisch oder dynamisch verknüpft und kommen in verschiedenen threading-Konfigurationen.
Sagen statisch gelinkten dlls sind, Sie beschreiben einen Versuchsaufbau, wo eine Anwendung .exe dynamisch links zu einer Bibliothek .dll und die Bibliothek intern statisch links auf die Laufzeit? Ich gehe davon aus, dass dies ist, was du meinst.
Erwähnenswert ist auch, dass jedes Modul (.exe-oder .dll) hat seinen eigenen Geltungsbereich für die Statik, d.h. eine Globale statische in einem .exe wird nicht die gleiche Instanz als Globale statische mit dem gleichen Namen in einem .dll.
Im Allgemeinen Fall kann daher nicht davon ausgegangen werden, dass code-Zeilen laufen in unterschiedliche Module verwenden die gleiche Implementierung der Laufzeitumgebung, des weiteren Sie werden nicht mit der gleichen Instanz von jedem statischen Zustand.
Daher bestimmte Regeln, die müssen befolgt werden beim Umgang mit Objekten oder Zeigern, die modulgrenzen kreuzen. Zuweisungen und deallocations werden müssen, treten in den gleichen Modul für einen bestimmten Adresse. Ansonsten ist der Haufen nicht entsprechen, und das Verhalten nicht definiert werden.
COM löst dieses Problem, diese mit Referenz-Zählung, Objekte löschen, selbst wenn der Referenzzähler null erreicht. Dies ist ein häufiges Muster, das verwendet wird, um das zu lösen abgestimmt Speicherort problem.
Andere Probleme vorhanden sein können, zum Beispiel windows definiert bestimmte Aktionen, wie z.B. Zuordnungsfehler behandelt werden, auf einer pro-thread-basis, nicht auf einer pro Modul basis. Dies bedeutet, dass code ausgeführt wird in Modul A auf thread-setup von Modul B kann auch führen Sie in unerwartete Verhalten.