hallo. ich habe in einem C-Programm folgende zeilen entdeckt: class CMessage; class CMsgs; die klassen werden später in einer anderen datein definiert. Was bewirken die "vordefinition" der klassen überhaupt ? Dann hab ich noch eine frage zu IMPORT_C und EXPORT_C. ich habe eine funktion die folgendermaßen definiert ist: IMPORT_C void Internalize( ... ); was bewirkt das IMPORT_C ? und wo kommt überhaupt EXPORT_C zum einsatz (EXPORT_C ist mir zufällig mal über den weg gelaufen) Danke. MfG
Das Schlüsselwort "class" gibt es in C nicht; entweder handelt es sich um C++ oder das ist irgendwo als Makro/Typ definiert. Das gleiche gilt für IMPORT_C/EXPORT_C.
IMPORT_C/EXPORT_C ist, soweit ich weiß, weder im C noch im C++-Standard definiert. Um die Bedeutung zu erfahren, musst du also wenigstens den verwendeten Compiler und die verwendeten Bibliotheken angeben (oder einfach selbst in der Doku nachschauen, da steht es bestimmt). Hat deine Beispiel-Funktion Internalize wirklich drei Punkte als Parameter? Du solltest bedenken, dass ... in Parameterlisten eine spezielle Bedeutung hat und als Platzhalter in Beispielen in den meisten Fällen ungeeignet ist. Zur "Vordefinition" der Klasse: Die heißt wirklich so, normal nimmt man aber die englische Bezeichnung "forward-declaration" (zumindest hab ich die deutsche eher selten gehört). Wie der Name schon sagt, wird dabei eine Klasse vorwärts deklariert. Die Deklaration sagt dem Compiler: "Es gibt eine Klasse mit dem Namen soundso", mehr nicht. Man kann im folgenden daher Zeiger und Referenzen auf diese noch nicht Klasse erzeugen. Man kann die Zeiger und Referenzen nur noch nicht benutzen, weil der Compiler die Klasse eben noch nicht wirklich kennt. Ebensowenig kann man Instanzen erstellen. Man benutzt solche Deklarationen zum Beispiel dafür: class B; class A { B* p; }; class B { A* p; }; Ohne forward-declaration von B wäre obiger Code nicht kompilierbar, da der Compiler immer eine der beiden Klassen zuerst sieht und zu dem Zeitpunkt die andere noch nicht kennt.
@Chris: Dann hab ich ja gut geraten ;) Ich verstehe zwar nicht den sinn von deinem beispiel aber die funktionsweise ist mir klar geworden. woher weisst du das mit den forward-declarations ? in meinen c / c++ büchern steht nix drin. Gibt es eingentlich fälle in denen man den beispielcode von dir wirklich benutzt ? EXPORT_C/IMPORT_C sind (sofern ich das jetzt richtig vertanden hab) Schlüsselwörter (oder wie man dazu sagt) die für DLLs benutzt werden. wenn ich eine funktion aus einer library benutzen will, dann muss ich IMPORT_C nehmen und wenn ich eine funktion in einer dll bereitstellen möchte dann muss ich EXPORT_C nehmen. Die funktion hat übrigends keine drei punkte als argument. ich hab nur den reichtigen code raus gemacht da er zeihmlich lang war und die sache somit nicht mehr auf eine zeile gepasst hätte. MfG Daniel Düsentrieb
forward-declarations braucht man zum Beispiel bei solchen Abhängigkeiten wie oben. Manchmal kommt es eben doch vor (auch wenn es dann häufig ein besseres Design geben mag), dass zwei Klassen sich gegenseitig benötigen. Ein (ziemlich schlechtes) Beispiel: Man hat zwei Klassen, die eine heißt DeviceContext, die andere Rectangle. DeviceContext hat in etwa die Funktion eines HDC unter Windows, stellt also eine Abstraktion der Zeichenhardware dar, meistens des Bildschirms. Rectangle definiert ein Rechteck. Der Einfachheit halber entscheidet man nun, dass Rectangle einen Zeiger auf ein DeviceContext-Objekt erhält, um sich jederzeit selbstständig zeichnen zu können. Ein DeviceContext-Objekt enthält nun aber seinerseits ein Rectangle, um die gültige Zeichenfläche anzugeben. Dieses Rectangle darf natürlich kein DeviceContext-Objekt enthalten, sonst hätte man eine Endlosschleife (dieses Rectangle würde wieder ein DC enhalten, dieses wieder Rectangle, und so weiter). Also enthält ein DeviceContext ein Rectangle-Objekt, dessen DeviceContext-Zeiger auf 0 zeigt. Um diese Klassen zu deklarieren, benötigt man zwingend forward-declarations: class DeviceContext; class Rectangle { DeviceContext* dc_; public: Rectangle(DeviceContext* p) : dc_(p) { }; }; class DeviceContext { Rectangle valid_area_; public: DeviceContext() : valid_area(0) { }; }; DeviceContext initialisiert den dc_-Zeiger seines Rectangles also mit 0 (der Doppelpunkt beim Konstruktor leitet eine Initialisiererliste ein). Wichtig ist hier, dass es andersrum nicht funktionieren würde; man kann also nicht DeviceContext vor Rectangle definieren. Die DeviceContext-Klasse enhält nämlich eine Rectangle-Instanz, keinen Zeiger. Eine Instanz darf aber erst verwendet werden, nachdem die Klasse vollständig definiert wurde. Der Compiler weiß ansonsten nicht, wie viel Bytes er für DeviceContext reservieren soll (da er die Größe von Rectangle noch nicht kennt).
> EXPORT_C/IMPORT_C sind (sofern ich das jetzt richtig vertanden hab) > Schlüsselwörter (oder wie man dazu sagt) Als Schlüsselworte werden AFAIK nur Sprachbestandteile (if, return, do und so Zeugs) bezeichnet. Was Du da hast sind Makros, die vom Präprozessor durch anderen Code ersetzt werden. Wenn's um DLLs geht, dann ist es sowieso erstmal implementierungsabhängig, der Sprachstandard kennt dieses Konzept nicht (was ihn auch unnötig speziell machen würde, und gerade das will man nicht). Wie bereits gesagt wurde, sollte die Dokumentation zu Deinem Compiler bzw. Deiner Entwicklungsumgebung mehr verraten. Etwas Googeln könnte auch schon helfen, so scheinen die Makros zu "__declspec(export)" aufzulösen. Grundregel: was mit oder _ anfängt ist Sache des Compilers bzw. der Implementierung, und wenn man damit rumhantiert wird man generell unportabel. Ich meine mich zu erinnern, daß es bei C-Compilern für Win32 auch schon üblich war mit __declspec den DLL-Kram zu handhaben, es handelt sich also scheinbar um eine (namenlose?) Konvention das unter Win32 einheitlich zu handhaben.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.