DLLs Vorteil/Nachtei/Tutorial?



  • Dabei müssen DLLs aber nicht unbedingt gelinkt werden, man kann auch DLLs erst später nachladen. (Für plugIns etwa)



  • TheToast schrieb:

    Dabei müssen DLLs aber nicht unbedingt gelinkt werden, man kann auch DLLs erst später nachladen. (Für plugIns etwa)

    Ich dachte, DLLs werden überhaupt nicht gelinkt. 😉

    Klar, beim späteren Laden muss man die Funktionen aber alle händisch extrahieren, per GetProcAddress, oder etwa nicht? (Ist natürlich auch bei Shared Libraries so.)



  • Natürlich werden die gelinkt, darum heißen sie ja Dynamic Link Library ...



  • TomasRiker schrieb:

    Natürlich werden die gelinkt, darum heißen sie ja Dynamic Link Library ...

    Wozu ist dann die .lib da? Wird die nur zum Spaß erzeugt?

    Ich dachte, es wird eine .lib erzeugt und die wird dann gelinkt, nicht die eigentliche DLL. Aber du kannst mich gerne aufklären.

    EDIT: Ich schreib mir in 7 Absätzen die Finger wund um zu erklären, wie ich die Unterschiede zwischen DLLs und Shared Libraries verstanden habe, und dann muss ich mir ein fettgeschriebenes "Link" bieten lassen. 🙄



  • Na, und die DLL wird zum Spaß erzeugt? 😃

    Das kannst du doch so nicht sehen. Die LIB dient nur als Stub (oder wie man sowas nennt), mehr ist das nicht. Ist sozusagen die Header-Datei für den Linker. Halt by-Design vom MSVC. Der rafft das anscheinend anders nicht... 😉



  • Artchi schrieb:

    Na, und die DLL wird zum Spaß erzeugt? 😃

    Natürlich nicht, aber sie wird nicht selber gelinkt.

    Artchi schrieb:

    Das kannst du doch so nicht sehen. Die LIB dient nur als Stub (oder wie man sowas nennt), mehr ist das nicht. Ist sozusagen die Header-Datei für den Linker.

    Also wird die LIB gelinkt?!

    Können andere Compiler DLLs ohne LIB linken?



  • Ja, MinGW macht das meines Wissens (bin aber kein wirklicher MinGW-Kenner), und auch Delphi braucht keine LIB (die brauchen nur ein Schlüsselwort im Source) um DLLs nutzen zu können.

    Aber ich bin selber kein DLL-Freund, ich benutze eigentlich nur DLLs von anderen.

    Was stört dich eigentlich an dem Stub? Nur weil der da ist, ist eine DLL statisch? DLL sagt doch eigentlich aus, was gemacht wird: dynamisch (zur Laufzeit) wird gelinkt. Eigentlich unmissverständlich, wie ich finde.



  • Artchi schrieb:

    Ja, MinGW macht das meines Wissens (bin aber kein wirklicher MinGW-Kenner), und auch Delphi braucht keine LIB (die brauchen nur ein Schlüsselwort im Source) um DLLs nutzen zu können.

    Ich meine mich bei MinGW an irgendwelche .a-Dateien zu erinnern. Bei Delphi kann ich mir alles vorstellen. 😃

    Artchi schrieb:

    Aber ich bin selber kein DLL-Freund, ich benutze eigentlich nur DLLs von anderen.

    Wie erreichst du dann Modularität?

    Artchi schrieb:

    Was stört dich eigentlich an dem Stub?

    Stört mich nicht wirklich, ich finde es allerdings auch nicht unbedingt elegant.

    Artchi schrieb:

    Nur weil der da ist, ist eine DLL statisch?

    Nein, aber die LIB, die man linkt.

    Artchi schrieb:

    DLL sagt doch eigentlich aus, was gemacht wird: dynamisch (zur Laufzeit) wird gelinkt. Eigentlich unmissverständlich, wie ich finde.

    Namen sind Schall und Rauch. 😉 Wichtig ist doch, was passiert.



  • .a sind die statische Lib und Mingw kann auch auch Dll's erstellen



  • Ich hab nochmal nachgelesen, MinGW erstellt auch Import Libraries, allerdings mit der Endung .a (die gleiche Endung benutzt er für statische Libraries, so wie jeder normale Unix-Compiler, .a entspricht also .lib).



  • Also Modularität erreiche ich nicht nur mit DLLs. Die erreiche ich auch mit LIBs oder Templates. Und eine *.cpp ist auch schon ein Modul. Ich kann auch durch abstrakte Klassen Abhängigkieten verringern usw. Deshalb verstehe ich jetzt nicht unbedingt, was DLLs zwangsweise mit Module zu tun haben? DLLs machen nur in wenigen Scenarien Sinn bzw. bringen in wenigen einen Vorteil. Aber ich glaube nicht, das man das nochmal durchkauen muß.



  • Artchi schrieb:

    Also Modularität erreiche ich nicht nur mit DLLs. Die erreiche ich auch mit LIBs oder Templates. Und eine *.cpp ist auch schon ein Modul. Ich kann auch durch abstrakte Klassen Abhängigkieten verringern usw. Deshalb verstehe ich jetzt nicht unbedingt, was DLLs zwangsweise mit Module zu tun haben?

    Stimmt schon, gibt halt noch den Fall des Modul-zur-Laufzeit-Ladens.

    Artchi schrieb:

    DLLs machen nur in wenigen Scenarien Sinn bzw. bringen in wenigen einen Vorteil. Aber ich glaube nicht, das man das nochmal durchkauen muß.

    Ja, die Frage, ob DLLs gelinkt werden oder nicht, interessiert mich jetzt doch mehr. :p

    Damit man mich nicht falsch versteht: Das Laden einer DLL per LoadLibrary ist kein Linken! Zumindest aus Applikationssicht.



  • Hier steht alles, was man wissen muss 😉
    http://msdn2.microsoft.com/en-us/library/ms681914.aspx



  • Ich hab mich hier weitergebildet.



  • Mr. N schrieb:

    Achtung: Ich kenne nur ELF-SharedLibs.

    DLLs werden bekanntlich indirekt gelinkt, über .libs.

    Ja, zum linken verwendet man .lib Files. Und? Unterschied?

    Soweit ich weiß ist eine DLL fast wie ein eigener Prozess, nur dass eben von außen über Namen und Nummer auf Funktionen zugegriffen werden kann.

    Eine DLL und ein Prozess sind grundlegend verschieden. Eine DLL ist ein eigenständiges PE Image, ja, aber das war's dann auch schon.

    Sie haben ja auch ihren eigenen Heap.

    Nope, haben sie nicht. Eine DLL kann eine "private" Speicherverwaltung verwenden wenn sie z.B. ihren eigenen Heap anlegt (z.B. in DllMain) oder einfach eine eigene Heap-Implementierung enthält. Eine DLL "hat" aber nicht einfach so ihren eigenen Heap. Eine DLL "hat" garkeinen Heap, zumindest keinen den sie vom Betriebssystem bekommen würde.

    Der Unterschied zwischen SOs und DLLs was die Speicherverwaltung angeht kommt daher dass mit SOs immer nur eine Kopie von z.B. malloc vorliegen kann (auch wenn mehrere SOs eine Funktion namens malloc implementieren), und diese eine Version wird dann für alle Aufrufe verwendet, egal wo diese stehen.
    Bei DLLs ist das anders. Ein Import in einer DLL oder Windows EXE ist sinngemäss nicht "verwende die Funktion namens malloc, egal wo sie herkommt" sondern "verwende die Funktion namens malloc aus der DLL XYZ.DLL".

    Beide Varianten haben Vorteile und Nachteile. Der Vorteil bei SOs ist dass man "global" Funktionen austaushen/überschreiben kann, bzw. dass eine Funktion eines Namens auch immer nur 1x vorliegt. Das erleichtert einiges wenn man eben soetwas wie ein Pluginsystem basteln möchte, oder wenn man mal eben ptmalloc durch tcmalloc ersetzen will.

    Der Vorteil von DLLs ist dass man immer genau das bekommt mit was man bei der Entwicklung des Programms gerechnet hat. Namenskonflikte zwischen unterschiedlichen DLLs die voneinander nichts wissen und sich dann irgendwann mal in einem Prozess "treffen" werden dadurch z.B. auch vermieden.
    Weiters ermöglicht es relativ einfach Code von verschiedensten Compilern (die auch gerne verschiedene Runtime Libraries verwenden dürfen) zu mischen -- ohne dass irgendwas neu compiliert werden muss. Dafür bezahlt man natürlich den Preis dass man sich an Berührungspunkten zwischen Code der mit unterschiedlichen Compilern/Runtimes compiliert wurde eben selbst darum kümmern muss dass gewisse Dinge funktionieren. Man darf also einen Zeiger der aus malloc in DLL A stammt nicht unbedingt mit free in DLL B freigeben.



  • Also:
    ein *.a in einem Linuxsystem (Posix) ist ein Archive. Dieses Archive enthält *.o. Objectdateien welche beim Compilieren erstellt werden. Dies ist auch unter Windows so. Unter Windows kann man die Opjectdateien auch linken.
    *.a sind vergleichbar mit LIB welche ja wie bereits gesagt wurde nur in Verbindung mit eine DLL fürktionieren. Die *.lib exportiert die definition der Funktionen welche in der DLL zu finden sind. (Einfach erklärt ohne Fachbegriffe zu nennen)
    Diese DLL kann man aber auch zur Laufzeit laden genauso wie man eine *.so zu Laufzeit lädt.
    Laufzeit heißt in diesem Fall nicht beim Programm start sondern wenn sie benötigt wird.
    Linkt man eine LIB oder .a dann wird die DLL,.so beim Programstart geladen.
    Linkt man aber eine .o braucht es keine DLL,.so.
    Keine Ahnung wie es unter Linux ist aber unter Windows ist es nicht richtig das die gleiche DLL nur einmal in den Speicher geladen wird. Hier kommt es darauf an aus welchem DIR die DLL geladen wird. Lädt das eine Prog die DLL aus c:\windows\system32 und die ein anderen Prog die gleiche DLL aus seinem Programmverzeichnis dann befoindet sich die gleiche DLL 2 Mal im Speicher.
    Windows macht die vermutlich anhand des Dateinamens und des Dir aus. Bennent man eine andere DLL um so wird auch diese DLL geladen aber er findet dann den Einsprungspunkt nicht. (Windowsfehler sinng.: Kann Einsprungspunkt nicht finden)



  • hustbaer schrieb:

    Mr. N schrieb:

    Achtung: Ich kenne nur ELF-SharedLibs.

    DLLs werden bekanntlich indirekt gelinkt, über .libs.

    Ja, zum linken verwendet man .lib Files. Und? Unterschied?

    Unterschied? Na, Shared Libraries linkt man direkt. Du hast eine libfoo.so und das reicht. Keine tausend verwirrenden Dateien. 😉

    hustbaer schrieb:

    Soweit ich weiß ist eine DLL fast wie ein eigener Prozess, nur dass eben von außen über Namen und Nummer auf Funktionen zugegriffen werden kann.

    Eine DLL und ein Prozess sind grundlegend verschieden. Eine DLL ist ein eigenständiges PE Image, ja, aber das war's dann auch schon.

    Naja, was mich zu diesem Satz verleitet hat, war halt GetModuleHandle.

    hustbaer schrieb:

    Sie haben ja auch ihren eigenen Heap.

    Nope, haben sie nicht. Eine DLL kann eine "private" Speicherverwaltung verwenden wenn sie z.B. ihren eigenen Heap anlegt (z.B. in DllMain) oder einfach eine eigene Heap-Implementierung enthält. Eine DLL "hat" aber nicht einfach so ihren eigenen Heap. Eine DLL "hat" garkeinen Heap, zumindest keinen den sie vom Betriebssystem bekommen würde.

    Was ist dann mit den Get*Heap-Funktionen? Hab ich das wiedermal falsch verstanden?

    hustbaer schrieb:

    Der Unterschied zwischen SOs und DLLs was die Speicherverwaltung angeht kommt daher dass mit SOs immer nur eine Kopie von z.B. malloc vorliegen kann (auch wenn mehrere SOs eine Funktion namens malloc implementieren), und diese eine Version wird dann für alle Aufrufe verwendet, egal wo diese stehen.

    Das stimmt nicht ganz, aber fast. In Shared Libraries kann man auch lokal linken. Wobei ich das eher verwendet habe um kleinere Binaries zu erzeugen. 😃 (Wenn ein Symbol lokal ist, braucht es nicht exportiert werden - kürzere Symboltabellen - und kann bei Nichtverwendung komplett rausgehauen werden.)

    hustbaer schrieb:

    Bei DLLs ist das anders. Ein Import in einer DLL oder Windows EXE ist sinngemäss nicht "verwende die Funktion namens malloc, egal wo sie herkommt" sondern "verwende die Funktion namens malloc aus der DLL XYZ.DLL".

    Beide Varianten haben Vorteile und Nachteile. Der Vorteil bei SOs ist dass man "global" Funktionen austaushen/überschreiben kann, bzw. dass eine Funktion eines Namens auch immer nur 1x vorliegt. Das erleichtert einiges wenn man eben soetwas wie ein Pluginsystem basteln möchte, oder wenn man mal eben ptmalloc durch tcmalloc ersetzen will.

    Richtig. Oder wenn man sicher gehen will, dass man Pointerownership zwischen Bibliotheken verschieben kann.

    hustbaer schrieb:

    Der Vorteil von DLLs ist dass man immer genau das bekommt mit was man bei der Entwicklung des Programms gerechnet hat. Namenskonflikte zwischen unterschiedlichen DLLs die voneinander nichts wissen und sich dann irgendwann mal in einem Prozess "treffen" werden dadurch z.B. auch vermieden.
    Weiters ermöglicht es relativ einfach Code von verschiedensten Compilern (die auch gerne verschiedene Runtime Libraries verwenden dürfen) zu mischen -- ohne dass irgendwas neu compiliert werden muss.

    Die Idee, mehrere C-Runtimes in einem Programm zu haben, ist mir irgendwie merkwürdig.

    Was ELF auch kann, was das Problem unter Linux vielleicht mindert, ist Symbolversionierung. Du kannst sagen, ich will eine spezielle Version des Symbols XYZ. Bzw. du linkst einfach eine spezielle Version der Library und wenn du dann auf nem anderen System eine andere Version bekommst schaut der, dass er dir die passenden Symbole liefert. (Ist nicht so ganz einfach und ich kenn mich damit auch nicht soo gut aus, aber ich kenne das Konzept.)

    hustbaer schrieb:

    Dafür bezahlt man natürlich den Preis dass man sich an Berührungspunkten zwischen Code der mit unterschiedlichen Compilern/Runtimes compiliert wurde eben selbst darum kümmern muss dass gewisse Dinge funktionieren. Man darf also einen Zeiger der aus malloc in DLL A stammt nicht unbedingt mit free in DLL B freigeben.

    Und das ist finde ich ein Problem. Es verhindert, dass ich einfach std::vector oder boost::shared_ptr-Objekte von DLL A nach DLL B gebe - wenn ich nicht per Konvention überall die selbe Runtime verwende. Oder eigene Allokatoren, aber das kann boost::shared_ptr wohl auch erst in Boost 1.34...

    Unix-Tom schrieb:

    Keine Ahnung wie es unter Linux ist

    Von welchem Unix kommt dein "Unix" im Namen? :p

    Unix-Tom schrieb:

    aber unter Windows ist es nicht richtig das die gleiche DLL nur einmal in den Speicher geladen wird. Hier kommt es darauf an aus welchem DIR die DLL geladen wird.

    Natürlich, weil er nicht davon ausgehen kann, dass das wirklich die selben DLLs sind.

    Wobei Windows auch irgendwie den SHA1 über die DLL bilden könnte oder so und anhanddessen identifizieren. 😃



  • @Mr. N:
    Du kannst nichts, sieh es ein. Es ist jedenfalls Respektlos hier von jedem die Postings so dermaßen auseinander zu nehmen, das sie gar keinen Sinn mehr ergeben. Sie es ein: Du hast verloren, also mach dich nicht loch lächerlich.



  • Mr. N schrieb:

    Unix-Tom schrieb:

    Keine Ahnung wie es unter Linux ist

    Von welchem Unix kommt dein "Unix" im Namen? :p

    Unix-Tom schrieb:

    aber unter Windows ist es nicht richtig das die gleiche DLL nur einmal in den Speicher geladen wird. Hier kommt es darauf an aus welchem DIR die DLL geladen wird.

    Natürlich, weil er nicht davon ausgehen kann, dass das wirklich die selben DLLs sind.

    Wobei Windows auch irgendwie den SHA1 über die DLL bilden könnte oder so und anhanddessen identifizieren. 😃

    [Zynismus]
    Windows kann auch einen Hash über Programmdateien bilden und die nur einmal in den Speicher laden.
    Windows kann auch nur aus DLL`s bestehen mit einem kleinen Startprogramm.
    Windows kann auch Kaffee kochen, Wäsche waschen, für mich zur Arbeit gehen.
    [/Zynismus]

    Windows macht aber all dies nicht ohne das es von MS implementiert wurde.
    Somit macht Windows auch keinen Hash über DLLS.
    Das unix in meinem Namen kommt daher da ich vor mit SCO-Open-Server begonnen habe.
    Wie sich in dem Fall *.so verhalten weiß ich dehlab nicht weil es mich nicht interessiert hat und ich somit auch nicht getestet habe.



  • Unix-Tom schrieb:

    Mr. N schrieb:

    Unix-Tom schrieb:

    Keine Ahnung wie es unter Linux ist

    Von welchem Unix kommt dein "Unix" im Namen? :p

    Unix-Tom schrieb:

    aber unter Windows ist es nicht richtig das die gleiche DLL nur einmal in den Speicher geladen wird. Hier kommt es darauf an aus welchem DIR die DLL geladen wird.

    Natürlich, weil er nicht davon ausgehen kann, dass das wirklich die selben DLLs sind.

    Wobei Windows auch irgendwie den SHA1 über die DLL bilden könnte oder so und anhanddessen identifizieren. 😃

    [Zynismus]
    Windows kann auch einen Hash über Programmdateien bilden und die nur einmal in den Speicher laden.
    Windows kann auch nur aus DLL`s bestehen mit einem kleinen Startprogramm.
    Windows kann auch Kaffee kochen, Wäsche waschen, für mich zur Arbeit gehen.
    [/Zynismus]

    Windows macht aber all dies nicht ohne das es von MS implementiert wurde.
    Somit macht Windows auch keinen Hash über DLLS.

    Das weiß ich auch. 🙄

    Unix-Tom schrieb:

    Das unix in meinem Namen kommt daher da ich vor mit SCO-Open-Server begonnen habe.

    Den Satz versteh ich nicht. 😕

    Unix-Tom schrieb:

    Wie sich in dem Fall *.so verhalten weiß ich dehlab nicht weil es mich nicht interessiert hat und ich somit auch nicht getestet habe.

    Naja, sorry, ich fühl mich ein wenig angegriffen, wenn sich jemand Unix-Tom nennt und dann viel mehr über DLLs (iiih) weiß als über Das Gute (TM). Ja, klar, ist total irrational, sorry.

    Dass du mir ständig Trivialitäten erklären willst hilft allerdings auch nicht unbedingt. ("DLLs und Shared Libraries sind das selbe Konzept", "gleiche DLLs werden nur geshared wenn sie im gleichen Verzeichnis liegen", "Windows macht den Hash aber nicht" - weiß ich auch, trivial!)

    [ELF Shared Libraries sind AFAIK deshalb besser, weil sie später entstanden sind, und man somit aus den Fehlern lernen konnte.]


Anmelden zum Antworten