Bedingte Kompilierung für mehrere OS
-
Hey @all,
und zwar wollte ich fragen wie man das am besten realisieren kann.
Und zwar hätte ich mir gedacht eine grafische oberfläche zu programmieren, die unter msdos(mit conio.h) und unter Linux(mit ncurses) funktioniert.
Mein Ansatz wäre folgender:
gui.hpp:#ifndef GUI_HPP #define GUI_HPP #include <string> #ifdef __LINUX__ #include <ncurses.h> class gui { ... }; #elif __MSDOS__ #include <conio.h> class gui { ... }; #endif
Nur wollte ich wissen, ob diese Möglichkeit funktioniert, oder ob man das besser lösen kann (ausser die NCurses lib für MS-DOS). Desweiteren wollte ich fragen was für #ifdef Deklarationen es für Windows, MS-Dos, Linux, Unix, oder sonstige gibt?
Ich meine zum Beispiel__WIN32__
Lg _freeze_
Edit: Hatte meine Code-Tags nicht genommen
-
Das kommt sehr auf den Compiler an. Aber du kannst das ja viel toller OO machen:
- Schnittstelle in Klassen definieren die einen Zeiger auf eine Implementierungsklasse haben (sie rufen im Prinzip immer nur das pendant der Implementierung auf)
- Abstrakte Implementierungsklassen
- DOS-Implementierung die im Hintergrund DOS-Systemfunktionen aus der <conio.h> aufruft.
- Linux-Implementierung die im Hintergrund Linux-Systemfunktionen aus der <ncurses.h> aufruft.
Der User macht dann nur noch sowas:
#include "deinelib.h" #include "deinelibimpl_dos.h" ... Klasse obj (new impl_dos);
MfG SideWinder
-
So was wie __LINUX__ __WIN32__ etc. lässt man sich am besten durch ein configure Skript setzen.
@Side
dann muss man ja wissen, welche Implementation man gerade will und baut sich dann einen haufen #ifdefs ein//gui.hpp #ifndef GUI_HPP #define GUI_HPP class gui { class gui_impl; gui_impl *impl; public: gui(); void do_gui(); //... }; #endif //gui.cpp #include "gui.hpp" #include "config.h" //wird von configure geschrieben #ifdef LINUX #include "gui_linux.cpp" #elif WIN32 #include "gui_win32.cpp" #else #error "GUI not implemented!" #endif //gui_linux.cpp struct gui::gui_impl { //PIMPL Idiom }; gui::gui() { } //Implementierung
-
Ja im Standard muss man leider selber wissen welches OS man hat, da es keine Möglichkeit gibt es rauszufinden.
Natürlich kann man dann noch schön schnell einen Header rumbauen der zwei TypeDefs für die Implementierungsklassen erstellt. Aber Hauptsache er bekommt diese #ifdef/#else/#endif-Teile aus den einzelnen Funktionen raus
!
MfG SideWinder
-
SideWinder schrieb:
Natürlich kann man dann noch schön schnell einen Header rumbauen der zwei TypeDefs für die Implementierungsklassen erstellt. Aber Hauptsache er bekommt diese #ifdef/#else/#endif-Teile aus den einzelnen Funktionen raus
!
mit deinem Vorschlag würde er sich diese ja in den Code einbauen :p
-
Nein würde er nicht...
MfG SideWinder
-
er benutzt intern ein interface, und übergibt dann im ctor eine klasse die vom interface abgeleitet ist, und die jeweilige funktionialität der dos/windows/linux/*nix implementation enthält.keine includes oder typedefs, nur eine allgemeine schnittstelle.
btw: templates funktionieren da auch wunderbar
-
Ob nun Templates oder Impl-Klassen frag ich ja grade im anderen Thread :D, genau das gleiche ist mir nämlich hier gekommen
MfG SideWinder
-
pimpl oder so, braucht's da auch nicht.
Einfach nur folgendes:
// gui.h #ifdef CURSES #include "curses/gui.h" #elif DOS #include "dos/gui.h" #endif
Und configure finde ich an der Stelle viel zu viel. Einfach den Makefile mit make CFLAGS=-DDOS bzw. CURSES aufrufen und gut.
Aber hauptsache es gibt ne gui.h für jede Plattform und nicht nur eine mit zig ifdefs drin.
-
Weiß nicht warum, gefällt mir aber nicht. Wenn der eine dritte Plattform findet muss der glatt die Headerdatei ändern anstatt einfach schnell noch ne Implementation dazuzuschreiben.
MfG SideWinder
-
Gegen diese Define-Dinger habe ich überhaupt eine Abneigung entwickelt. Die kann man so schlecht in Namespaces packen und machen dann nur Ärger.
MfG SideWinder
-
SideWinder schrieb:
Weiß nicht warum, gefällt mir aber nicht. Wenn der eine dritte Plattform findet muss der glatt die Headerdatei ändern anstatt einfach schnell noch ne Implementation dazuzuschreiben.
Er muss genau, diesen einen einzigen Header um einen Fall erweitern. Ansonsten wird einfach nur <platform>/gui.h dazu gepackt.
Eure "OOP-Lösungen" machen eigentlich gar keinen Sinn (d.h ich sehe jetzt keinen). Um ein define, welches man dem Compiler mitgibt damit er nur das richtige kompiliert, kommt man ohnehin nicht rum.
Gegen diese Define-Dinger habe ich überhaupt eine Abneigung entwickelt. Die kann man so schlecht in Namespaces packen und machen dann nur Ärger.
Nur wenn man die überall mitten im Code plaziert.
-
DrGreenthumb schrieb:
Er muss genau, diesen einen einzigen Header um einen Fall erweitern. Ansonsten wird einfach nur <platform>/gui.h dazu gepackt.
Ok, nicht ganz. Dasselbe nochmal mit gui.cpp.
Trotzdem, irgendwelche Basisklassen oder Templates sind überflüssig. Einfaches Austauschen der Dateien reicht.
-
gui.cpp hat meistens ein Neukompilieren von Libraries zur Folge.
BTW: http://www.c-plusplus.net/forum/viewtopic.php?t=80929 hier hat mir Hume gerade erklärt, dass für dich wohl Templates besser wären als diese Impl-Klassen.
MfG SideWinder
-
SideWinder schrieb:
gui.cpp hat meistens ein Neukompilieren von Libraries zur Folge.
Äh, ja, natürlich. Hier geht es doch darum, zu entscheiden für welches OS kompiliert wird.
Zeig mir mal, wie du das mit den Templates machen willst. Da schreibst du dann
#ifdef UNIX #include unixgui.h #endif int main() { #ifdef UNIX FensterKlasse<Unix> klasse; #endif }
Das ist doch doppelt gemoppelt und bringt gar nichts.
-
Bezieht sich dein Posting nun auf den Quote oder auf die Templates?
MfG SideWinder
-
Der erste Satz bezog sich auf das Zitat und das Codebeispiel zeigt, dass Templates hier überhaupt nichts bringen.
-
mittels templates brauch man auch nur an einer stelle einen einzigen parameter verändern, und man kann das ganze prog auf ein andres betriebssystem ausrichten, wenn man ein gutes design hat.
du musst stattdessen 1000 defines machen...auch nich wirklich schön.
-
Nein, du hast es nicht verstanden. Es sind 2(!) defines und die brauchst du genauso, wenn du zusätzlich noch den Template-Kram rumbaust.
Probiert das ganze erstmal aus, bevor noch mehr solche Argumente kommen.
-
ich brauch kein define.
ich ersetze nämlich in der main einfach einen template parameter, das programm kompiliert bei mir dann für ein komplett andres betriebssystem, weil der eine template parameter bewirkt, dass alle andren klassen die benutzt werden auch auf das betriebssystem umgeschaltet werden, dh ich hab in keinem header ein define, ich hab in der main kein define ich hab in keiner cpp ein define, sondern regel alles(!) über ein template(bzw über eine typliste, dann änder ich nur nen typedef)Probier das ganze erstmal aus, bevor noch mehr solche Argumente kommen.