Kreuz und quer durch C++, alles ist dabei ...
-
Der aus dem Westen ... schrieb:
Also erst mal ein neues Projekt, Anwendungstyp DLL. So war's doch, oder?
Ja.
Der aus dem Westen ... schrieb:
Da ich eine neue DLL ohne alte Funktionen erstellen will, muss ich dllexport verwenden, da so neue Funktionen hinzugefügt werden.
Das verstehe ich nicht ganz. Du musst Funktionen usw. als "dllexport" deklarieren, damit sie von außerhalb der DLL verfügbar werden. Sonst kannst du die DLL ja gar nicht benutzen. War es das, was du meintest?
Der aus dem Westen ... schrieb:
Zuerst Header erstellen, Deklarationen hinzufügen (damit man auf die Liste zugreifen kann), dann Funktionen definieren und ein Schutzmakro einbinden. Anschliessend kompilieren.
Im Prinzip ja. Bitte beachte aber, dass im Falle von Templates *kein* "dllexport" verwendet werden darf. Hier sind ja die Definitionen bereits im Header vorhanden und es wird überhaupt kein Code für die DLL erzeugt.
Der aus dem Westen ... schrieb:
Und was die STL angeht: Ich habe vor, ein guter - ich meine ein WIRKLICH guter - Programmierer zu werden. Aber wenn ich nur den einfachen Weg gehe und mich nie mit der Interna der STL einlasse, werde ich es auch zu nichts bringen. Dazu will ich auch sagen, dass ich erst 18 bin und vor einem Jahr mit C++ angefangen habe, und ich habe die Befürchtung, dass ich den Anschluss verpassen könnte, DESHALB nehme ich den harten Weg und beschäftige mich mit Speicherverwaltung, dynamischen Arrays und komplexen Listen (denn komplexen ist die ganze Matrix schon). Und nur, wenn ich ABSOLUT nicht klarkomme (wie zum Beispiel mit selbstprogrammierten streams), greife ich auf Hilfe von Ausserhalb zu.
Ich möchte dich keineswegs davon abbringen, Dinge verstehen zu wollen, die du verwendest! Und Algorithmen und Datenstrukturen zu verstehen, gehört sicherlich dazu, ein guter Programmierer zu sein.
Bloß klang dein Beitrag so, als wolltest du gar nichts verwenden, das du nicht vorher verstanden hast. Und das erschien mir ein Bischen zu viel des Guten. Mehr wollte ich gar nicht sagen. Ein guter Programmierer versteht sich nämlich auch auf die Kunst, gute Dinge wieder zu verwenden. Damit er sein Ziel nicht aus den Augen verliert...
Stefan.
-
DStefan schrieb:
Das verstehe ich nicht ganz. Du musst Funktionen usw. als "dllexport" deklarieren, damit sie von außerhalb der DLL verfügbar werden. Sonst kannst du die DLL ja gar nicht benutzen. War es das, was du meintest?
Bingo! Genau das. In der Header muss die Deklaration + __declspec(dllexport) stehen. Im DLL-Projekt muss dann die Header eingebunden sein, dann kann man die Funktionen definieren, oder?
DStefan schrieb:
Im Prinzip ja. Bitte beachte aber, dass im Falle von Templates *kein* "dllexport" verwendet werden darf. Hier sind ja die Definitionen bereits im Header vorhanden und es wird überhaupt kein Code für die DLL erzeugt.
Für Templates fällt die DLL ins Wasser. Aber was ist mit statischen Bibliotheken?
DStefan schrieb:
Ich möchte dich keineswegs davon abbringen, Dinge verstehen zu wollen, die du verwendest! Und Algorithmen und Datenstrukturen zu verstehen, gehört sicherlich dazu, ein guter Programmierer zu sein.
Bloß klang dein Beitrag so, als wolltest du gar nichts verwenden, das du nicht vorher verstanden hast. Und das erschien mir ein Bischen zu viel des Guten. Mehr wollte ich gar nicht sagen. Ein guter Programmierer versteht sich nämlich auch auf die Kunst, gute Dinge wieder zu verwenden. Damit er sein Ziel nicht aus den Augen verliert...
Klar, sonst wären Vererbung, Templates und RTTI wohl verschwendet, oder?
-
Der aus dem Westen ... schrieb:
Für Templates fällt die DLL ins Wasser. Aber was ist mit statischen Bibliotheken?
Dieselbe Antwort. DLLs enthalten fertig übersetzten Code, der unmittelbar ausgeführt wird, wenn man die jeweilige Funktion aufruft.
Im Falle von Templates (und so lange dein Compiler nicht das Keyword "export" unterstützt) wird der Code eines Templates am Ort der Verwendung/Instanziierung erzeugt. Das ist nicht ganz dasselbe wie inline aber so ähnlich.
Also kann man aus Templates keine DLLs erzeugen.
Stefan.
-
Aber mein Compiler unterstützt "export". Nur weiss ich nicht, was mir das bringt.
-
Aber mein Compiler unterstützt "export".
Aus deinem Post kann man erkennen, dass du Visual C++ nutzt und das unterstützt export nicht!
-
Stimmt. Da habe ich einen Anweisung verwechselt.
Also, entweder bin ich zu blöd dafür, oder mein Compiler hasst mich (was gut sein kann, da er sich immer aufhängt, wenn ich mit der rechten Maustaste klicke), um DLLs zu erstellen. Ich habe eine Klasse, die ... aber seht selbst:
// Headerdatei SimpleClassDLL.h // #pragma once #ifndef _SIMPLECLASSDLL_H #define _SIMPLECLASSDLL_H #include <iostream> using std::cout; using std::endl; class CSimpleClass { public: void __declspec(dllexport) Hello(); void __declspec(dllexport) Bye(); }; #endif // Quellcodedatei SimpleClassDLL.cpp // #include "SimpleClassDLL.h" void CSimpleClass::Hello() { cout<<"Hallo!"<<endl; } void CSimpleClass::Bye() { cout<<"Auf Wiedersehen!"<<endl; }Hier existeren zwei Dateien: SimpleClassDLL.h, die die Deklaration der Klasse vornimmt, und SimpleClassDLL.cpp, die die beiden einzigen Funktionen der Klasse definiert. Ich kompiliere meinen Code und heraus kommt eine DLL von ungefähr 37 KB Größe. Dann will ich meine Funktionen in einem anderen Projekt unterbringen. Dazu kopiere ich den Header der Klasse und die DLL in den Projektodner und binde dann die Headerdatei ein:
// Ein anderes Projekt, Main.cpp // #include "SimpleClassDLL.h" int main() { CSimpleClass SC; SC.Hello(); SC.Bye(); cin.get(); return 0; }Hier wird die neue Klasse eingebunden, eine Instanz erstellt und die beiden Funktionen der Klasse aufgerufen. Nein, das heisst, sie SOLLEN aufgerufen werden, aber mein Linker quaselt was von wegen "nichtaufgelöstem extenem Symbol" (es heisst immer, Laufzeitfehler seien die schlimmsten Fehler, aber ich denke, Linkerfehler können einen in den Wahnsinn treiben). Kann mir jemand verraten, was ich falsch mache?
-
1. Du musst die gesamte Klasse exportieren (dllexport nach "class").
2. Du musst in dem Projekt, welches die DLL benutzt die Klasse auch wieder IMportieren - wie Du das am besten machst, ohne zwei Header für dieselbe Klasse zu erzeugen, hat DStefan schön beschrieben.
3. Beim Erstellungsprozess der DLL wird eine LIB-Datei erzeugt. Diese musst Du beim nutzenden Projekt einbinden, damit die undefined references des Linkers befriedigt werden.
-
Also ...
Erstens:
class __declspec(dllexport) CSimpleClass{/*...*/};Zweitens (nach der Erstellung der DLL):
class __declspec(dllimport) CSimpleClass{/*...*/};Drittens: Die .LIB mitkopieren. Richtig?
-
1./2. Ja, wobei Du die Datei nicht ändern musst. Lies den Beitrag von DStefan nochmal

3. Ja, und in den Projektoptionen bei "zusätzliche Linkerabhängigkeiten" eintragen, oder (ein MSVC-Konstrukt), in die Headerdatei folgendes schreiben:
#pragma comment(lib,"dllname.lib")
-
Den habe ich bereits gelesen :D.
OK, wird noch heute ausprobiert.
-
Davon abgesehen: Alles was mit Bibliothekten etc. zu tun hat, ist kein ANSI C++ (Der Thread gehört eher in "MFC (Visual C++)"). Es gibt keine dll & ähnliches in ANSI C++.