Forum: PC-Programmierung Wozu DLL registrieren unter Windows?


von Peter (Gast)


Lesenswert?

Hallo,

ich sehe immer wieder Threads, wo es Probleme beim Registrieren einer 
DLL gibt. Z.B. hier:

http://stackoverflow.com/questions/22933957/unable-to-register-my-dll-using-regsvr32-but-via-ide-works

Was hat das mit dem regsvr32 auf sich?
Wozu überhaupt registrieren? Die DLL wird auf den Rechner kopiert und 
die Applikation ruft darin Funktionen auf - das geht doch auch so.

Gruß Peter

von Dr. Sommer (Gast)


Lesenswert?

Peter schrieb:
> das geht doch auch so.
Nicht wenn das eine COM-DLL ist. Dann wird die über eine GUID statt 
Pfad/Dateiname angesprochen.

von Micha L. (milu)


Lesenswert?

Da bist du auf COM gestoßen. Im Kern ist COM die Spezifikation einer 
binären Schnittstelle. Meist wird C++ zur Implementierung benutzt, weil 
das am leichtesten geht. Kein Zufall, sondern genauso geplant.

Richtig, eine herkömmliche DLL braucht nicht registriert werden. Sie 
wird entweder über ihre Importbibliothek (kleine LIB Datei) mit der EXE 
verlinkt oder zur Laufzeit via LoadLibrary geladen. Und fertig ist die 
Laube.

Aber was, wenn man systemweit Komponenten bereitstellen möchte, ohne dem 
Client das Implementierungsdetail »DATEINAME.DLL« bekannzumachen? Weil 
vielleicht verschiedene Versionen der Komponente parallel existieren 
müssen?

Dann braucht man eine Indirektion, und die geht über die Windows 
Registrierungsdatenbank. Die zu registrierende DLL muß DllRegisterServer 
implementieren und darüber ihre API Kennungen (GUIDs für Klassen und 
Schnittstellen: CLSID und IID) dem System bekanntmachen.

DllRegisterServer
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682162(v=vs.85).aspx

COM Registry Keys
http://msdn.microsoft.com/en-us/library/windows/desktop/ms678477%28v=vs.85%29.aspx

Ein Client muß dann nur die entsprechenden GUIDs kennen und kann über 
CoCreateInstance und QueryInterface versuchen, Zeiger auf die 
Schnittstellen der Komponente zu laden.

Es steckt einiges mehr hinter COM und für einen Programmierer denk ich 
ist es ein sehr interessantes Modell, das aber ein wenig Lernaufwand 
erfordert. Ein Riesenbatzen von Windows beruht auf COM, es ist also kein 
Schnickschnack, sondern eine tragende Säule des Systems.

von Peter II (Gast)


Lesenswert?

Es gibt bei COM-Dlls auch die Möglichkeit sie ohne Registrierung zu 
verwenden. Das kann man einsetzen, wenn man Software ohne Installation 
und Admin Rechte verwenden will.

Dafür muss dann aber wieder der Name der DLL bekannt sein.

von Peter (Gast)


Lesenswert?

Erstmal vielen Dank für die ganzen Auskünfte. Die haben mir sehr 
geholfen!

Micha Lu schrieb:
> Aber was, wenn man systemweit Komponenten bereitstellen möchte, ohne dem
> Client das Implementierungsdetail »DATEINAME.DLL« bekannzumachen? Weil
> vielleicht verschiedene Versionen der Komponente parallel existieren
> müssen?

Das verstehe ich nicht ganz:
1. Was sind systemweite Komponenten?
2. Worin genau liegt das Problem jedem Client (was meinst Du mit Client 
in dem Fall?) ein LoadLibrary("MyDLL.dll") zu verpassen?
3. verschiedene Versionen der Komponente? Wieso verschiedene 
Komponenten? Beispiel?

Peter II schrieb:
> Es gibt bei COM-Dlls auch die Möglichkeit sie ohne Registrierung zu
> verwenden.

Sind COM-DLLs und normale DLLs zwei verschiedene paar Schuhe oder 
unterscheiden die sich nur in der Implementierung von 
DllRegisterServer() / DllUnregisterServer() ?
Mit anderen Worten: Wenn ich die beiden Funktionen in der normalen DLL 
einfüge, wird sie dann zur COM-DLL?

Gruß Peter

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Peter schrieb:
> Sind COM-DLLs und normale DLLs zwei verschiedene paar Schuhe

O ja. COM sieht eine völlig andere Art des Aufrufs von in DLLs (bzw. 
anderen COM-Servern) enthaltenen Funktionen vor, als das bei normalen 
DLLs üblich ist. Das Stichwort hier lautet "Automation", und ermöglicht 
es, Funktionen aus COM-DLLs u.a. auch aus VB-Script heraus zu verwenden.

Der unschöne Aspekt daran ist, daß gerade das Interface mit C/C++ und 
das Debuggen des ganzen Krams ein ziemlicher Krampf im Arsch ist.

> Wenn ich die beiden Funktionen in der normalen DLL
> einfüge, wird sie dann zur COM-DLL?

Nein.

von Micha L. (milu)


Lesenswert?

Peter schrieb:
> Micha Lu schrieb:
>> Aber was, wenn man systemweit Komponenten bereitstellen möchte, ohne dem
>> Client das Implementierungsdetail »DATEINAME.DLL« bekannzumachen? Weil
>> vielleicht verschiedene Versionen der Komponente parallel existieren
>> müssen?
>
> Das verstehe ich nicht ganz:
> 1. Was sind systemweite Komponenten?

Systemweit verfügbar, so wie eine DLL in System32 oder WinSxS. Gedacht 
im Gegensatz zu einer DLL im Unterordner irgendeiner Anwendung im 
Programmverzeichnis, welcher nicht im Suchpfad liegt sondern nur 
ebenjener Anwendung bekannt ist und sonst nicht genutzt wird.

Die Komponente ist eben das COM Ding: Ein Satz zusammengehöriger 
Schnittstellen, die IUnknown ordnungsgemäß implementieren. Eine 
Komponente ist, was die COM Spezifikation beschreibt. Implementiert wird 
sie in einer oder mehreren DLLs, aber die DLL ist dabei wirklich nur ein 
Implementierungsdetail und hat an sich nichts mit COM zu tun. Aber 
irgendwie muß man sie ja implementieren, und in Windows bot sich da eben 
die DLL an, die sich ja schon in der Produktion bewährt hatte. :)

> 2. Worin genau liegt das Problem jedem Client (was meinst Du mit Client
> in dem Fall?) ein LoadLibrary("MyDLL.dll") zu verpassen?

Ein Client ist der Nutzer einer Funktionalität. Wenn ich eine DLL habe, 
dann sind die davon abhängigen Exen die Clients. Wenn ich eine Funktion 
habe, dann nenne ich die aufrufenden Stellen Clientcode.

Worin das Problem liegt? Für C gibt es kein Problem. Für C ist die DLL 
vollkommen ausreichend. Für C ist alles in Butter.

Aber nun gibt es ja auch C++. Objekte und so. Wollen ja die meisten 
haben. Und da gehen die Probleme los.

Stichwort »name mangling«: Um dem Linker die Überladungen einer Funktion 
unterscheidbar zu machen, kodiert der Compiler die Argumente der 
Funktion in den Symbolnamen. Und da kocht jeder Compiler sein eigenes 
proprietäres Süppchen. Es gibt keinen Standard für diese Umbenennung, 
und damit keine Interoperabilität. Ich brauch genau den Linker, mit dem 
die Kompilate erstellt wurden, gegen die ich linken will. Den Quellcode 
hab ich vielleicht nicht, weil ich er der Firma Xy gehört und nicht 
offenliegt.

Stichwort »binary interface«: Wenn ich einer Klasse in C++ einen 
privaten Member dazugebe, ändert sich die binäre Definition der Klasse. 
Sagen wir, hier kommt Version 2 der Klasse CBlubbel, die ist viel besser 
als Version 1, aber dafür mußte ein privater Member eingeführt werden. 
Privat, also kann ich immer noch dagegen kompilieren, ohne Änderungen am 
Clientcode. Ja, aber wenn ich nun im System meine Blub.dll durch die 
neue Version ersetze, werden alte Clients sehr wahrscheinlich die 
Grätsche machen, weil sie den Speicherplatz für CBlubbel Exemplare 
falsch berechnen, nämlich ohne den Platz für den neuen privaten Member. 
Also kann ich meine Blub.dll nicht so einfach ersetzen; ich müßte sie 
Blub2.dll nennen. Und bei der nächsten Verbesserung wieder. Und so 
weiter, fröhliche Vermüllung, wer soll das wieder aufräumen?

Wenn ich die Schnittstelle meiner C++ Bibliothek als »extern "C"« 
auslege, dann habe ich diese Probleme nicht; aber dann kann ich eben 
(wie mit C) nur globale Funktionen anbieten, und keine Objekte, weil 
»extern "C"« die Implementierungsgrundlagen von C++ OO außer Kraft 
setzt.

> 3. verschiedene Versionen der Komponente? Wieso verschiedene
> Komponenten? Beispiel?

Version 1 von Bla.dll hat einen schweren Fehler oder läuft inakzeptabel 
langsam. Nun kommt Version 2 mit dem Fix. Dieser verändert leider die 
binäre Schnittstelle von CBlabla. Kein Problem für laber.exe, welche ich 
zusammen mit Bla.dll in einer neuen Version ausliefere. Aber Pech für 
schnack.exe, welche von einem anderen Anbieter gegen Bla.dll entwickelt 
wurde und nicht zeitnah aktualisiert werden kann.

Stell dir einfach vor, du bist Microsoft oder Adobe oder auch eine 
kleine Firma oder ein Einmannbetrieb, aber jedenfalls ein Anbieter 
fundamentaler C++ OO Funktionalität mit Clientcode außerhalb deiner 
Kontrolle. Da mußt du immer kompatibel bleiben. Und trotzdem verbessern 
und bereinigen und liefern. Mit C++ Bordmitteln geht das nicht. COM 
wurde erdacht (von 1988-93 bei Microsoft), um dies Problem zu lösen, und 
es funktioniert.

von Peter (Gast)


Lesenswert?

Micha Lu schrieb:
> Stichwort »name mangling«: Um dem Linker die Überladungen einer Funktion
> unterscheidbar zu machen, kodiert der Compiler die Argumente der
> Funktion in den Symbolnamen. Und da kocht jeder Compiler sein eigenes
> proprietäres Süppchen. Es gibt keinen Standard für diese Umbenennung,
> und damit keine Interoperabilität. Ich brauch genau den Linker, mit dem
> die Kompilate erstellt wurden, gegen die ich linken will. Den Quellcode
> hab ich vielleicht nicht, weil ich er der Firma Xy gehört und nicht
> offenliegt.

Das kann ich unterdrücken: extern "C" ... , aber das schreibst Du ja 
auch wie ich sehe ...

Micha Lu schrieb:
> Wenn ich die Schnittstelle meiner C++ Bibliothek als »extern "C"«
> auslege, dann habe ich diese Probleme nicht; aber dann kann ich eben
> (wie mit C) nur globale Funktionen anbieten, und keine Objekte, weil
> »extern "C"« die Implementierungsgrundlagen von C++ OO außer Kraft
> setzt.

Globale Funktionen? Ist doch egal, wenn ich denen einen Index/Zeiger auf 
eine DLL-interne Struktur mitgebe und die verschiedenen Objekte 
ebenfalls in der DLL in einer Liste sammle und verwalte, oder nicht?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Peter schrieb:
> st doch egal, wenn ich denen einen Index/Zeiger auf
> eine DLL-interne Struktur mitgebe und die verschiedenen Objekte
> ebenfalls in der DLL in einer Liste sammle und verwalte, oder nicht?

Das Konzept ist jedenfalls nicht neu; was wohl verbirgt sich hinter 
einem "Handle"? Eben. Genau für diese Situation ist das da.

von Micha L. (milu)


Lesenswert?

Ja, handle, natürlich kann man das machen, und erwiesenermaßen 
funktioniert das hervorragend; dann hat man aber »nur« eine API à la 
Win32 und keine »echte OO API«.

COM dagegen erlaubt mehr OO in der API. Wie wichtig das nun ist … 
vielleicht Geschmacksfrage. Aber der Nutzen von COM beschränkt sich ja 
nicht auf API Kosmetik.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.