Verständnisfrage (dynamische) DLL
-
Hallo,
beschäftige mich seit Kurzem mit ein wenig DLL.
So wie ich es verstehe, heißt dynamisch also nur einmal im Speicher geladen und kann paralell von mehreren Programmen aufgerufen werden.
Meine Frage, wenn ich in einer DLL eine Variable erzeuge, wieso kann ich nicht aus mehren Programmen auf diese Variable zugreifen. Die DLL ist doch nur einmal im Speicher, oder?

Beispiel:
#include <windows.h> #include <stdio.h> static int i = 0; DLLEXPORT BOOL APIENTRY DllMain( HANDLE hModule , DWORD ul_reason_for_call , LPVOID lpReserved) { char buf[255]; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: sprintf(buf, "Test: %d", ++i); MessageBox(NULL, buf, "Test", 0); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: sprintf(buf, "Test: %d", --i); MessageBox(NULL, buf, "Test", 0); break; default: } return TRUE; }Wenn ich diese DLL übersetze und ein Programm starte, das eine Funktion daraus aufruft, ist die Abfolge des Zählers bei jedem Programm gleich: zuertst 1 und dann 0.
Verstehe ich hier etwas nicht?
Danke für die Mühe
Alex
-
Eine DLL wird für jede Programminstanz einmal geladen. Mehrere Starts der Anwendung heißt also das die DLL auch mehrmals geladen wird.
Wenn du Daten zwischen 2 oder mehr Anwendungen austauschen willst, such mal nach Shared Memory (bzw. Mapped Memory), ansonsten musst du die Daten einfach in eine Datei schreiben und vom anderen Programm lesen lassen.
-
.... schrieb:
Hallo,
beschäftige mich seit Kurzem mit ein wenig DLL.
So wie ich es verstehe, heißt dynamisch also nur einmal im Speicher geladen und kann paralell von mehreren Programmen aufgerufen werden....
Das ist ein gar nicht mal so seltenes Mißverständnis !
Es muß heißen "...heißt dynamisch also nur einmal auf die Festplatte geladen ..." !
Was daran toll ist ?
-> Wenn Du eine oft genutzte Funktionalität (sagen wir mal: Die Ausgabe einer Meldung in einer MessageBox) aus einer statischen lib verwendest, wird der Programmcode (sagen wir mal 500 KB), der das macht in jede .exe fest eingelinkt.
-> Hast Du nun 100 executables, die diese Funktionalität nutzen wollen, belegt allein das 50 MB auf der Platte. (im Dynamischen Fall wären das einmal 500 KB in einer DLL)
-> Machst Du das für 10 Funktionalitäten, hast Du die Wahl zwischen:- einer 5-MB-DLL und
- 500 MB in executables.
Außerdem kannst Du auf diese Weise einen Fehler in der Implementierung der Funktionalität in EINER DLL fixen und alle 100 executables arbeiten mit der korrigierten Fassung. (Andernfalls mußt Du 100 executables ggf. von 10 verschiedenen Herstellern fixen lassen).
Ist also schon ein Vorteil.
Gruß,
Simon2.
P.S.: Andererseits hat natürlich die Kopplung von 100 exes durch eine DLL auch Nachteile - z.B. wenn eine Software die Funktionalität in einer anderen Version braucht als eine andere.
-
also, erst einmal vielen Dank für die Antworten!

Vellas schrieb:
Wenn du Daten zwischen 2 oder mehr Anwendungen austauschen willst, such mal nach Shared Memory (bzw. Mapped Memory)...
Das würde mich sehr interessieren! Geht das auch mit win und api???
@Simon2
Danke für die ausführliche Info ;). Das habe ich noch nie in so einer ausführliche Formulierung vorgefunden!Alex
-
.... schrieb:
Vellas schrieb:
Wenn du Daten zwischen 2 oder mehr Anwendungen austauschen willst, such mal nach Shared Memory (bzw. Mapped Memory)...
Das würde mich sehr interessieren! Geht das auch mit win und api???
Klar, guck mal nach folgenden Funktionen:
CreateFile, CreateFileMapping, MapViewOfFile, UnmapViewOfFile und CloseHandle.
Außerdem solltest du dir evtl. noch CEvent ansehen, damit kannst du von einer Hauptanwendung eine andere zu verarbeitende Anwendung benachrichtigen, wenn eine bestimmte Aktion in der Hauptanwendung gemacht wurde (z.B. Verarbeitung abgebrochen).Greetz
-
Soweit ich weiß werden DLLs tatsächlich nur einmal geladen,
allerdings werden lokale Variablen für jede Instanz separat
erzeugt; (eigenes Datensgment pro Instanz)Die geladene DLL-Instanz kann ja vom Programm (exe) direkt
angesprochen werden. Daher muß die DLL ins Datensegment
der exe eingebunden sein.Gemeinsam genutzt wird nur der Programmcode - insofern wird
schon Speicher gespart. Die Ladezeit einer DLL, die bereits
von einem anderen Programm benutzt wird sollte daher wesentlich
kürzer sein als wenn die DLL das erste Mal geladen wird.Schönen Gruß, khw
-
Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
khw hat recht. Und wenn man versucht den Programmcode zu ändern, gilt "Copy-On-Write" (wenn man das Recht dazu hat).
-
PE Images, und damit auch DLLs, werden nicht geladen, die werden in den Speicher abgebildet ("gemappt"). Pages die gebraucht werden werden dabei geladen, andere nicht unbedingt. Solange ein Image an die "preferred load address" geladen wird (=jede EXE und mit etwas Glück alle DLLs die eine "passende" base address verwenden) muss der Loader da drinnen auch keine Relocations fixen, und eine Page einer DLL verbraucht auch nur eine Page, egal wie viele Prozesse die verwenden.
Fängt nun ein Prozess an in solcherart gemappte Pages reinzuschreiben dann macht Windows beim ersten Schreibzugriff auf diese Page eine private Kopie für den entsprechenden Prozess.
All das gilt (vereinfacht gesagt) für Pages aus Sections die nicht "shared" markiert sind. Pages aus Sections die "shared" markiert sind sind von diesem "Copy-On-Write" nicht betroffen - d.h. Änderungen in "shared" sections sehen ALLE Prozesse.
Wenn du also diverse Variablen in einer DLL zwischen allen Prozessen teilen willst, dann packe die einfach in eine "shared" Section hinein. Dazu machst du ein DEF File und definierst da drinnen eine eigene Section ala so:
LIBRARY "LiLaLibrary" BASE=0x12300000 SECTIONS .my_shared_section READ WRITE SHAREDAlternativ kannst du (ab VC 7.1 zumindest) ohne DEF File einfach jenes in irgendein Code-File schreiben:
#pragma section(".my_shared_section",read,write,shared)Und dann packst du deine Variablen in diese section rein, ala so:
#pragma data_seg(".my_shared_section") long g_v1 = 0; int g_v2 = 0; //... #pragma data_seg()Blubb

-
Oh ha! Sehr beachtlich! Da lermt man ja ordentlich was Neues dazu!
Besten Dank an euch alle!!!
Werd ich morgen geleich mal ausprobieren

Alex