[X] Portabilität
-
du hast dich beim link auf wxwidgets verschrieben
-
lösch mich ( komischweise hab ich gar nicht 2 mal auf absenden geklickt )
BR
-
"Linux ist ja auch nur ein Windows"
Wenn wir eine Anwendung von Windows auf Linux (oder umgekehrt) portieren wollen, gibt es da denn große Unterschiede?
Ja, es gibt sie. Nein, es gibt sie nicht. Ja was nun? Die Unterschiede zwischen Linux und Windows liegen offensichtlich in der Architektur, das spielt aber für uns keine Rolle. Uns interessiert, wie sich unser Code unter den beiden Systemen verhält. Wenn wir von vornherein wissen, dass unsere Anwendung auf mehreren Betriebssystemen laufen muss, dann können wir uns von vornherein vieles erleichtern.
Kaum eine Anwendung kommt ohne externe Libraries aus. In der Designphase ist es wichtig sich für plattformunabhängige Bibliotheken zu entscheiden. So mag zum Beispiel wxWidgets eine bessere Wahl als Gtk sein, da es sowohl unter Windows als auch unter Linux nativ aussieht. Vor allem unter Windows sind hier auch noch lizenzrechtliche Probleme zu beachten, sodass zum Beispiel Qt oft nicht die beste Wahl ist. Denn eine Qt Lizenz kostet viel Geld und die freie Variante steht unter der GPL. Hier punktet wieder Gtk. Es ist also nicht leicht die richtige Entscheidung zu treffen.
Wenn wir also wissen, dass wir unsere Anwendung portabel gestalten wollen, erleichtern wir uns durch portable Bibliotheken später viel Arbeit. Allerdings, wie der Teufel so spielt, weiß man nicht alles im Voraus. Deshalb sollte man, sofern es vernünftig (das heißt ohne großem Mehraufwand) möglich ist, zu portablen Libraries tendieren. Boost, stlsoft und ACE sind hier gute Anlaufstellen.
Es ist aber nicht immer möglich (und sinnvoll) eine plattformunabhängige Lösung zu verwenden. In diesen Fällen kann es sinnvoll sein, die plattformabhängige Bibliothek zu wrappen oder per MVC (oder dem oft einfacherem Doc/View) Pattern zu integrieren. Denn wenn man an 100.000 Stellen den Code ändern muss um das Programm portieren zu können, ist der Aufwand oft viel zu hoch.
Gerade die Ausgabelogik von der Businesslogik zu trennen kann hier Gold wert sein. Denn es kann sehr leicht passieren, dass man ein GUI-Toolkit wie zum Beispiel VCL plötzlich nicht auf der Zielplattform verwenden kann. Wenn man sich schön an MVC oder Doc/View gehalten hat, kann man recht schön nur das GUI austauschen. Dass dies nicht immer so einfach ist, hat Marcus Bäckmann beim ersten Forentreffen eindrucksvoll gezeigt. Eine andere GUI-Architektur kann zu viele/wenige Aktualisierungen vom Controller verlangen und dadurch die Performance stark beeinflussen. In solchen Situationen muss man Refaktorieren.
Oft können es aber auch die kleinen Unstimmigkeiten sein, die das Debuggen auf der neuen Plattform zur Hölle machen. Es ist deshalb durchaus sinnvoll boost/cstdint.hpp zu verwenden. Boost definiert hierin Integer-Typen mit garantierter Größe. Sodass man boost::int_least16_t schreiben kann und sich sicher sein kann einen Typen mit mindestens 16 Bit bekommen zu haben. Falsche Typengrößen sind nur selten ein Problem, aber dank boost kann man sie gratis fast ganz vermeiden.
Der Rest der Arbeit läuft ähnlich ab, wie wenn man eine Library wrappt – denn nichts anderes tut man. Das Schöne daran ist, dass man gleich ein OO-Interface über diese Funktionen legen kann. Da dies aber viel Arbeit ist, ist es oft sinnvoll nur "on demand" etwas zu wrappen. Das heißt nur dann, wenn man es wirklich braucht. Stlsoft bietet da eine gute Anlaufstelle.
Wenn man für 2 oder mehr Plattformen entwickelt, wird man an verschiedenen Stellen ein Problem verschieden lösen müssen, auch wenn die Bibliotheken alle plattformunabhängig sind (wir leben ja leider nicht in einer perfekten Welt). Dann ist es wichtig den Code nicht durch viele #ifdefs unleserlich zu machen. Eine gute Lösung hierbei ist es, für jede Plattform eine eigene Source Datei anzulegen. Dadurch hat man zwar mehr Code zu warten und man muss etwaige Bugfixe auf andere Plattformen übertragen, aber man erkauft sich dafür leichter lesbareren Code. Denn bei vielen #ifdefs kann man leicht den Überblick verlieren und was wohl am schlimmsten ist: auf eine neue Plattform portieren kann unnötig kompliziert werden (weil wir schon wieder an 100.000 einzelnen Stellen den Code ändern müssen).
Um die Transparenz zu wahren, kann man Proxy Dateien verwenden. Man erstellt pro Plattform einen eigenen Verzeichnisbaum (zum Beispiel code/programm/win32, code/programm/linux, ...) und legt an der zentralen Stelle (bei uns zum Beispiel code/programm) eine Proxy Datei ab. Diese inkludiert lediglich die richtige Plattformdatei. Dank dem Präprozessor kann man hier recht simpel #ifdefs machen um die richtige Plattform auszuwählen. Der Clientcode bekommt davon nichts mit.
Eine Foo.cpp sieht dann in etwa so aus:
#if MY_OS == MY_WINDOWS #include "win32/Foo.cpp" #elif MY_OS == MY_LINUX #include "linux/Foo.cpp" #elif MY_OS == MY_WASANDERES #include "wasanderes/Foo.cpp" #endif
In einer zentralen config Datei bestimmt man dann das Betriebssystem oder lässt den Anwender das richtige #define setzen.
Der Clientcode linkt jetzt nur Foo.cpp und muss sich nicht mehr darum kümmern ob es in Wirklichkeit win32/Foo.cpp oder linux/Foo.cpp ist.
Oft ist aber ein viel größeres Problem die Compilerunabhängigkeit. Denn auf Plattformunabhängigkeit lässt sich leicht achten indem man alle systemabhängigen Libraries wrappt. Aber Compilerunbhängigkeit besteht meistens daraus, Compilerbugs zu umgehen. Dieses Unterfangen kann recht mühselig sein, vor allem da es kaum Ressourcen zu diesem Thema gibt.
Eine einfache Möglichkeit besteht darin, schon recht früh mit mehreren Compilern zu testen. Idealerweise lässt man hierbei die Unit Tests mit den verschiedenen Compilern laufen. Das Problem hierbei ist, dass viele Compiler nur kommerziell verfügbar sind. Die Linkliste von www.c-plusplus.net hat hier aber ein paar interessante Compiler Ressourcen.
Ein interessanter Link zu den Compilerunterschieden ist vielleicht auch die Dokumentation einer alten Version einer CGI/Library, die ich einmal geschrieben habe. Sie zeigt die Workarounds die nötig waren diese Bibliothek unter verschiedenen Compilern einzusetzen. Der Link ist aber eher für Leute die Spaß am Basteln haben, denn wenn man unter zeitdruck steht, dann sollte man lieber diese Spielereien lassen und lieber konservativeren Code verwenden.
Viel tun um sich gegen Compilerprobleme zu schützen kann man leider nicht. Die Unittests können einem viele Probleme ersparen, da man rechtzeitig viele Inkompatibilitäten entdeckt. Oft ist es auch sinnvoll zu templatelastigen Code (vor allem Template Metaprogrammierung) zu meiden, da damit noch viele Compiler große Probleme haben. Ein großes Nein sind hier vor allem Template Template Argumente. Oft muss man leider auch das Interface ändern um um einen Compilerbug herumzukommen. Frühes Testen kann hier viel Ärger ersparen.
Das Deployment von Crossplattform-Anwendungen ist ein nächstes großes Kapitel. Hier teilt es sich in 2 Teile auf: Bibliotheken und Anwendungen.
Bibliotheken:
Da man diese in der Regel von Source kompilieren muss (Bibliotheken in Binärform sind meistens nur dann sinnvoll, wenn man sie als DLL/SO vertreibt) muss man viele verschiedene Makefiles anbieten. wxWidgets entwickelt deshalb an bakefile, einer Möglichkeit für viele verschiedene Compiler Makefiles zu erstellen.Unter Unix kann und sollte man natürlich autotools verwenden. Das Problem stellt sich eigentlich nur in der Windows Welt. Denn hier herrschen viele verschiedene Compiler vor und es existieren keine autotools um das Kompilieren zu vereinfachen. Andere Möglichkeiten der Distribution bieten Scons und CMake, da sie portable Wrapper um Make sind. Der Nachteil ist, dass der Anwender diese installiert haben muss.
Bei Anwendungen ist die Sache sogar viel komplizierter. Das große Problem hierbei ist, dass eine Anwendung die unter Windows sehr beliebt ist unter Linux vielleicht keine Anwender findet. Denn hier muss man nicht nur technische Aspekte beachten, sondern vor allem die Systemintegration. Nicht jeder BSD-Desktop hat eine "System Notification Area", sodass eine Anwendung die sich darauf verlässt, recht schnell unbedienbar werden kann.
Auch andere Aspekte wie Look & Feel und sonstige Usability Guidelines unterscheiden sich von Plattform zu Plattform. Dies kann oft ein viel größeres Problem als alle technischen Gründe werden, denn wenn das Programm nicht verwendet/gekauft wird, dann bringt die Plattformunabhängigkeit nichts. Wenn die Anwendung unter allen Plattformen gleich aussieht und sich gleich benimmt so kann dies für User die diese Anwendung unter mehreren Plattformen betreiben ein Vorteil sein, für User die nur eine Plattform benützen ist dies allerdings ein Problem, denn die Anwendung sieht nicht so aus und verhält sich nicht so wie es der User erwarten würde.
Weiters kostet Plattformunabhängigkeit auch Performance. Oft ist das nicht sehr wichtig, in manchen Fällen kann es aber relevant werden. Plattformunabhängigkeit heißt im Prinzip nichts anderes als Abstraktion und Abstraktion hat manchmal versteckte Kosten. Eine dieser Kosten ist folgendes: plattformspezifische Optimierungen. Da wir die Zielplattform nicht kennen bzw. nicht genau wissen was alles Ziel werden wird oder wir den kleinsten gemeinsamen Nenner dieser Plattformen finden müssen, nehmen wir uns die Möglichkeit speziell für diese Plattform zu optimieren.
Alles in allem ist es nicht leicht portable Software zu entwickeln. Meistens bedeutet Plattformunabhängigkeit höhere Komplexität, schlechtere Performance, schlechtere Wartbarkeit oder suboptimales Userinterface. Man muss immer abwägen, was wichtiger ist. Denn Portabilität ist nicht das einzige Qualitätsmerkmal einer Software und schon gar nicht das Wichtigste.
-
ich würde vorschlagen, du machst das [R] erst inn Threadnamen, wenn das [T] verschwindet, sonst mühen sich die Rechtschreibprüfer umsonst ab. Schreibs am besten noch mal DICK in den Namenkonventionenthread: NICHT MEHR ALS EIN BUCHSTABE ALLEIN IM THREADNAMEN ERLAUBT!!!!!
Mr. B
-
ne kleine rechtschreibprüfung und gut ist
-
"Linux ist ja auch nur ein Windows"
Wenn wir eine Anwendung von Windows auf Linux (oder umgekehrt) portieren wollen, gibt es da denn große Unterschiede?
Ja, es gibt sie. Nein, es gibt sie nicht. Ja was nun? Die Unterschiede zwischen Linux und Windows liegen offenbar in der Architektur***;*** das spielt aber für uns keine Rolle. Uns interessiert, wie sich unser Code unter den beiden Systemen verhält. Wenn wir von vornherein wissen, dass unsere Anwendung auf mehreren Betriebssystemen laufen muss, dann können wir uns von vornherein vieles erleichtern.
Kaum eine Anwendung kommt ohne externe Librarys aus. In der Designphase ist es wichtig***,*** sich für plattformunabhängige Bibliotheken zu entscheiden. So mag zum Beispiel wxWidgets eine bessere Wahl als Gtk sein, da es sowohl unter Windows als auch unter Linux nativ aussieht. Vor allem unter Windows sind hier auch noch lizenzrechtliche Probleme zu beachten, sodass zum Beispiel Qt oft nicht die beste Wahl ist***, denn*** eine Qt Lizenz kostet viel Geld und die freie Variante steht unter der GPL. Hier punktet wieder Gtk. Es ist also nicht leicht***,*** die richtige Entscheidung zu treffen.
Wenn wir also wissen, dass wir unsere Anwendung portabel gestalten wollen, erleichtern wir uns durch portable Bibliotheken später viel Arbeit. Allerdings, wie der Teufel so spielt, weiß man nicht alles im Voraus. Deshalb sollte man auch, sofern es nicht allzu großen zusätzlichen Aufwand verursacht, zu diesen portablen Librarys greifen. Boost, stlsoft und ACE sind hier gute Anlaufstellen.
Es ist aber nicht immer möglich (und sinnvoll) eine plattformunabhängige Lösung zu verwenden. In diesen Fällen kann es sinnvoll sein, die plattformabhängige Bibliothek zu wrappen oder per MVC (oder dem oft einfacherem Doc/View) Pattern zu integrieren***, denn*** wenn man an 100.000 Stellen den Code ändern muss***,*** um das Programm portieren zu können, ist der Aufwand oft viel zu hoch.
Gerade die Ausgabe***-*** von der Businesslogik zu trennen kann hier Gold wert sein***, denn*** es kann sehr leicht passieren, dass man ein GUI-Toolkit wie zum Beispiel VCL plötzlich nicht auf der Zielplattform verwenden kann. Wenn man sich schön an MVC oder Doc/View gehalten hat, kann man recht schön nur das GUI austauschen. Dass dies nicht immer so einfach ist, hat Marcus Bäckmann beim ersten Forentreffen eindrucksvoll gezeigt. Eine andere GUI-Architektur kann zu viele/wenige Aktualisierungen vom Controller verlangen und dadurch die Performance stark beeinflussen. In solchen Situationen muss man refaktorieren.
Oft können es aber auch die kleinen Unstimmigkeiten sein, die das Debuggen auf der neuen Plattform zur Hölle machen. Es ist deshalb durchaus sinnvoll***,*** boost/cstdint.hpp zu verwenden. Boost definiert hierin ~?????? was ist das denn fürn wort?~ Integer-Typen mit garantierter Größe***, sodass*** man boost::int_least16_t schreiben kann und sich sicher sein kann***,*** einen Typen mit mindestens 16 Bit bekommen zu haben. Falsche Typengrößen sind nur selten ein Problem, aber dank boost kann man sie gratis fast ganz vermeiden.
Der Rest der Arbeit läuft so ähnlich ab***,*** wie als wenn man eine Library wrappt – denn etwas anderes tut man ja nicht. Das Schöne daran ist, dass man gleich ein OO-Interface über diese Funktionen legen kann. Da dies aber viel Arbeit ist, ist es oft sinnvoll etwas nur "on demand" zu wrappen (das heißt nur dann, wenn man es wirklich braucht***)***. Stlsoft stellt dafür eine gute Anlaufstelle dar.
Wenn man für zwei oder mehr Plattformen entwickelt, wird man an verschiedenen Stellen ein Problem verschieden lösen müssen, auch wenn die Bibliotheken alle plattformunabhängig sind (wir leben ja leider nicht in einer perfekten Welt). Dann ist es wichtig***,*** den Code nicht durch viele #ifdefs unleserlich zu machen. Eine gute Lösung hierbei ist es, für jede Plattform eine eigene Source Datei anzulegen. Dadurch hat man zwar mehr Code zu warten und man muss etwaige Bugfixes auf andere Plattformen übertragen, aber man erkauft sich dafür leichter zu lesenden Code. Denn bei vielen #ifdefs kann man leicht den Überblick verlieren***,*** und was wohl am schlimmsten ist: auf eine neue Plattform Portieren kann unnötig kompliziert werden (weil wir schon wieder an 100.000 einzelnen Stellen den Code ändern müssen).
Um die Transparenz zu wahren, kann man Proxy-Dateien verwenden. Man erstellt pro Plattform einen eigenen Verzeichnisbaum (zum Beispiel code/programm/win32, code/programm/linux, ...) und legt an der zentralen Stelle (bei uns zum Beispiel code/programm) eine Proxy-Datei ab. Diese inkludiert lediglich die richtige Plattformdatei. Dank des Präprozessors kann man hier recht simpel #ifdefs machen***,*** um die richtige Plattform auszuwählen. Der Clientcode bekommt davon nichts mit.
Eine Foo.cpp sieht dann in etwa so aus:
#if MY_OS == MY_WINDOWS #include "win32/Foo.cpp" #elif MY_OS == MY_LINUX #include "linux/Foo.cpp" #elif MY_OS == MY_WASANDERES #include "wasanderes/Foo.cpp" #endif
In einer zentralen config-Datei~vllt. besser: Konfigurationsdatei?~ bestimmt man dann das Betriebssystem oder lässt den Anwender das richtige #define setzen.
Der Clientcode linkt jetzt nur Foo.cpp und muss sich nicht mehr darum kümmern***,*** ob es in Wirklichkeit win32/Foo.cpp oder linux/Foo.cpp ist.
Ein oft viel größeres Problem ist aber die Compilerunabhängigkeit. Denn auf Plattformunabhängigkeit lässt sich leicht achten***,*** indem man alle systemabhängigen Librarys wrappt. Aber Compilerunbhängigkeit besteht meistens daraus, Compilerbugs zu umgehen. Dieses Unterfangen kann recht mühselig sein, vor allem da es kaum Ressourcen zu diesem Thema gibt.
Eine einfache Möglichkeit besteht darin, schon recht früh mit mehreren Compilern zu testen. Idealerweise lässt man hierbei die Unit Tests mit den verschiedenen Compilern laufen. Das Problem hierbei ist, dass viele Compiler nur kommerziell verfügbar sind. Die Linkliste von www.c-plusplus.net hat hier aber ein paar interessante Compilerressourcen.
Ein interessanter Link zu den Compilerunterschieden ist vielleicht auch die Dokumentation einer alten Version einer CGI/Library, die ich einmal geschrieben habe. Sie zeigt die Workarounds***,*** die nötig waren***,*** diese Bibliothek unter verschiedenen Compilern einzusetzen. Der Link ist aber eher für Leute***,*** die Spaß am Basteln haben, denn wenn man unter Zeitdruck steht, dann sollte man diese Spielereien lassen und lieber konservativeren Code verwenden.
Viel tun***,*** um sich gegen Compilerprobleme zu schützen***,*** kann man leider nicht. Die Unittests können einem viele Probleme ersparen, da man rechtzeitig viele Inkompatibilitäten entdeckt. Oft ist es auch sinnvoll zu templatelastigen Code (vor allem Template Metaprogrammierung) zu meiden, da damit noch viele Compiler große Probleme haben. Ein großes Nein sind hier vor allem Template Template~gewollt oder extra?~ Argumente. Oft muss man leider auch das Interface ändern***,*** um um einen Compilerbug herumzukommen. Frühes Testen kann hier viel Ärger ersparen.
Das Deployment von Crossplattform-Anwendungen ist ein nächstes großes Kapitel. Hier teilt es sich in zwei Teile auf: Bibliotheken und Anwendungen.
Bibliotheken:
Da man diese in der Regel von Source kompilieren muss (Bibliotheken in Binärform sind meistens nur dann sinnvoll, wenn man sie als DLL/SO vertreibt)***,*** muss man viele verschiedene Makefiles anbieten. wxWidgets entwickelt deshalb an bakefile, einer Möglichkeit für viele verschiedene Compiler Makefiles zu erstellen.Unter Unix kann und sollte man natürlich Autotools verwenden. Das Problem stellt sich eigentlich nur in der Windows-Welt, denn hier herrschen viele verschiedene Compiler und es existieren keine Autotools, um das Kompilieren zu vereinfachen. Andere Möglichkeiten der Distribution bieten Scons und CMake, da sie portable Wrapper um Make sind. Der Nachteil ist, dass der Anwender diese installiert haben muss.
Bei Anwendungen ist die Sache sogar viel komplizierter. Das große Problem hierbei ist, dass eine Anwendung ,die unter Windows sehr beliebt ist, unter Linux vielleicht keine Anwender findet***, denn*** hier muss man nicht nur technische Aspekte beachten, sondern vor allem die Systemintegration. Nicht jeder BSD-Desktop hat eine "System Notification Area", sodass eine Anwendung***,*** die sich darauf verlässt, recht schnell nicht mehr zu bedienen sein kann.
Auch andere Aspekte wie Look & Feel und sonstige Usability Guidelines unterscheiden sich von Plattform zu Plattform. Dies kann oft ein viel größeres Problem als alle technischen Gründe werden, denn wenn das Programm nicht verwendet oder gekauft wird, dann bringt die Plattformunabhängigkeit nichts. Wenn die Anwendung unter allen Plattformen gleich aussieht und sich gleich benimmt***,*** so kann dies für User***,*** die diese Anwendung unter mehreren Plattformen betreiben***,*** ein Vorteil sein. Für User, die nur eine Plattform benutzen, ist dies allerdings ein Problem, denn die Anwendung sieht nicht so aus und verhält sich nicht so***,*** wie es der User erwarten würde.
Des Weiteren kostet Plattformunabhängigkeit auch Performance. Oft ist das nicht sehr wichtig, in manchen Fällen kann es aber relevant werden. Plattformunabhängigkeit heißt im Prinzip nichts anderes als Abstraktion***,*** und Abstraktion hat manchmal versteckte Kosten. Eine dieser Kosten ist folgendes: plattformspezifische Optimierungen. Da wir die Zielplattform nicht kennen oder nicht genau wissen***,*** was alles Ziel werden wird***,*** oder wir den kleinsten gemeinsamen Nenner dieser Plattformen finden müssen, nehmen wir uns die Möglichkeit speziell für diese Plattform zu optimieren.
Alles in allem ist es nicht leicht***,*** portable Software zu entwickeln. Meistens bedeutet Plattformunabhängigkeit höhere Komplexität, schlechtere Performance, schlechtere Wartbarkeit oder nicht optimales Userinterface. Man muss immer abwägen, was wichtiger ist. Denn Portabilität ist nicht das einzige Qualitätsmerkmal einer Software und schon gar nicht das wichtigste.
---------------------------------------------------------------------------------------
FAZIT/KOMMENTAR:
Nimms mir nich übel, aber mich würde interessieren, was du früher in Deutsch hattest. Es gab doch schon ziemlich viele Fehler, aber, wenn man dies als eine Verschönerung des Ergebnisses sehen will, es waren wirklich sehr viele von derselben Natur. Insgesamt konnte ich deinen Artikel nicht immer sofort nachvollziehen, was aber auch daran liegen könnte, dass ich keine Ahnung auf diesem Gebiet habe. (Das soll jetzt keineswegs eine Heruntermachung deinerseits sein oder etwa ein Kommentar, wie er unter Arbeiten steht, werden - ich bin nur Korrekturleser und möchte Tipps geben )
- Weniger Anglizismen
- Weniger Anglizismen
- NOCH weniger Anglizismen (gut, auf dem Gebiet der Informatik ist das manchmal schwierig, aber "Workarounds", "Performance", "wrappen" etc. Da tust du mir echt was an - das ist GRAUSELIGER Stil für mich)
So wie es anfing, war es doch schon gut. Da hast du kaum Anglizismen gebraucht, aber zum Ende hin... - vor dem "um" als ein konsekutiver Nebensatz steht immer ein Komma (ich hoffe, du verstehst das jetzt - falls nich, sprich mich noch einmal drauf an)
- Nutze zum Ausdruck des Grundes mal ab und an was anderes als "denn". Und wenn du schon "denn" schreibst, dann bitte nicht als allein stehenden Satz, sondern als Satzgefüge, sprich (meistens) mit Komma davor.
- Der Plural von eingedeutschten englischen Wörtern wird nach der deutschen Grammatik gehandhabt. Es heißt als so "Librarys", "Handys" (was ja eigentlich nich mals englisch ist), "Hobbys", weil es im Singular "Library", "Handy" bzw. "Hobby" heißt. Bei den Wörtern "Girlie" oder "Teenie" heißt es dementsprechend "Girlies" bzw. "Teenies", da man sie im Singular eben wie o. g. schreibt. Deutsche Sprache einfache Sprache.
Ham wa heut nich schon wieda wat gelernt, nech?
Mr. B
P. S.: Was gut war: kein "weil das ist so" und überhaupt das Ausweichen auf "denn". Manche denken ja gar nich da dran.
-
Wenn du schon so ein "Problem" mit den englischen wörtern hast. Dann benutze doch nicht bitte falsche. Ich finde Librarys einfach hässlich, dann lieber Bibliotheken
BR
-
Mr. B schrieb:
Nimms mir nich übel, aber mich würde interessieren, was du früher in Deutsch hattest.
Habe mit ner 2 maturiert (Abitur gemacht).
Aber was rechtschreibung/grammatik betrifft war ich nie eine besondere Leuchte, weil ich alles immer nach gefühl macheWeniger Anglizismen
Ne, ich mag anglizismen. Ich finde die treffen es meistens einfach besser.
[*] vor dem "um" als ein konsekutiver Nebensatz steht immer ein Komma (ich hoffe, du verstehst das jetzt - falls nich, sprich mich noch einmal drauf an)
Ne, Beistrichsetzung habe ich nie verstanden Aber dafür habe ich ja dich
[*] Nutze zum Ausdruck des Grundes mal ab und an was anderes als "denn". Und wenn du schon "denn" schreibst, dann bitte nicht als allein stehenden Satz, sondern als Satzgefüge, sprich (meistens) mit Komma davor.
ok
[*] Der Plural von eingedeutschten englischen Wörtern wird nach der deutschen Grammatik gehandhabt. Es heißt als so "Librarys", "Handys" (was ja eigentlich nich mals englisch ist), "Hobbys", weil es im Singular "Library", "Handy" bzw. "Hobby" heißt. Bei den Wörtern "Girlie" oder "Teenie" heißt es dementsprechend "Girlies" bzw. "Teenies", da man sie im Singular eben wie o. g. schreibt. Deutsche Sprache einfache Sprache.
Ich finde Libraries zwar ästhetischer, aber du hast recht.
Ham wa heut nich schon wieda wat gelernt, nech?
es vergeht kein tag an dem ich nichts neues lerne. vielen dank für die lehrstunde
Ein paar kurze Fragen noch:
warum "offenbar" statt "offensichtlich"?
offenbar drückt für mich eine überraschung aus. "Offenbar war schon jemand vor uns hier". Oder auch "ich werde dir jetzt etwas offenbaren" - immer eine kleine art der überraschung. Während ein offensichtlich doch eher etwas offen sichtbares was jeder wissen sollte ist.warum "nicht optimal" statt "suboptimal"? Ich mag suboptimal irgendwie...
den rest verstehe ich zwar nicht immer (zB die kommasetzung) aber das wird schon so passen andere fehler von mir waren echt dumm
@evilissimo:
ich finde librarys auch hässlich, aber um ehrlich zu sein: delfin finde ich noch hässlicher also im prinzip: die deutsche rechtschreibung ist hässlich (für mich). Aber wenn es so richtig ist, dann muss ich es auch so machen.Und Bibliotheken mag ich nicht. Denn in meinen Augen ist Library einfach der Term dafür.
-
Shade Of Mine schrieb:
Ein paar kurze Fragen noch:
warum "offenbar" statt "offensichtlich"?wer den zwiebelfisch gelesen hat, weiß jetzt die antwort. ich war mir gestern abend nich ganz sicher. habe gerade noch mal nachgeguckt und festgestellt, dass zwischen "offenbar" und "offensichlich" nicht der geringste unterschied besteht, deshalb darfst du beides benutzen.
Shade Of Mine schrieb:
warum "nicht optimal" statt "suboptimal"? Ich mag suboptimal irgendwie...
weil es kein "suboptimal" gibt. "optimal" heißt "das beste", weshalb man "optimal" auch nicht steigern kann. und das "unterbeste" ergibt keinen sinn. mir fiel aber auch nix besseres ein außer "nicht optimal".
Shade Of Mine schrieb:
Und Bibliotheken mag ich nicht. Denn in meinen Augen ist Library einfach der Term dafür.
nein. zwischen bibliothek und library gibt es ebenfalls nicht den geringsten unterschied, nur das bibliothek ein schönes deutsches wort ist.
apropos, da fällt mir was ein: such mal nach "anm" in meinem post. habe zwei mal [anm] machen müssen, allerdings wusste ich noch nich, dass es das tag noch nich gab.
Mr. B
-
Mr. B schrieb:
nein. zwischen bibliothek und library gibt es ebenfalls nicht den geringsten unterschied, nur das bibliothek ein schönes deutsches wort ist.
Genauso wie Vorlage <-> Template. Ich mag den englischen Term lieber, weil das universeller ist.
apropos, da fällt mir was ein: such mal nach "anm" in meinem post. habe zwei mal [anm] machen müssen, allerdings wusste ich noch nich, dass es das tag noch nich gab.
Template Template passt schon so.
hierin - vielleicht besser darin? Alles in cstdint.hpp halt.
Konfigurationsdatei passt und ist besser.
-
dann bitte ich dich, das im endartikel selbst zu übernehmen
Mr. B
-
"Linux ist ja auch nur ein Windows"
Wenn wir eine Anwendung von Windows auf Linux (oder umgekehrt) portieren wollen, gibt es da denn große Unterschiede?
Ja, es gibt sie. Nein, es gibt sie nicht. Ja was nun? Die Unterschiede zwischen Linux und Windows liegen offenbar in der Architektur; das spielt aber für uns keine Rolle. Uns interessiert, wie sich unser Code unter den beiden Systemen verhält. Wenn wir von vornherein wissen, dass unsere Anwendung auf mehreren Betriebssystemen laufen muss, dann können wir uns von vornherein vieles erleichtern.
Kaum eine Anwendung kommt ohne externe Librarys aus. In der Designphase ist es wichtig, sich für plattformunabhängige Bibliotheken zu entscheiden. So mag zum Beispiel wxWidgets eine bessere Wahl als Gtk sein, da es sowohl unter Windows als auch unter Linux nativ aussieht. Vor allem unter Windows sind hier auch noch lizenzrechtliche Probleme zu beachten, sodass zum Beispiel Qt oft nicht die beste Wahl ist, denn eine Qt Lizenz kostet viel Geld und die freie Variante steht unter der GPL. Hier punktet wieder Gtk. Es ist also nicht leicht, die richtige Entscheidung zu treffen.
Wenn wir also wissen, dass wir unsere Anwendung portabel gestalten wollen, erleichtern wir uns durch portable Bibliotheken später viel Arbeit. Allerdings, wie der Teufel so spielt, weiß man nicht alles im Voraus. Deshalb sollte man auch, sofern es nicht allzu großen zusätzlichen Aufwand verursacht, zu diesen portablen Librarys greifen. Boost, stlsoft und ACE sind hier gute Anlaufstellen.
Es ist aber nicht immer möglich (und sinnvoll) eine plattformunabhängige Lösung zu verwenden. In diesen Fällen kann es sinnvoll sein, die plattformabhängige Bibliothek zu wrappen oder per MVC (oder dem oft einfacherem Doc/View) Pattern zu integrieren, denn wenn man an 100.000 Stellen den Code ändern muss, um das Programm portieren zu können, ist der Aufwand oft viel zu hoch.
Gerade die Ausgabe- von der Businesslogik zu trennen kann hier Gold wert sein, denn es kann sehr leicht passieren, dass man ein GUI-Toolkit wie zum Beispiel VCL plötzlich nicht auf der Zielplattform verwenden kann. Wenn man sich schön an MVC oder Doc/View gehalten hat, kann man recht schön nur das GUI austauschen. Dass dies nicht immer so einfach ist, hat Marcus Bäckmann beim ersten Forentreffen eindrucksvoll gezeigt. Eine andere GUI-Architektur kann zu viele/wenige Aktualisierungen vom Controller verlangen und dadurch die Performance stark beeinflussen. In solchen Situationen muss man refaktorieren.
Oft können es aber auch die kleinen Unstimmigkeiten sein, die das Debuggen auf der neuen Plattform zur Hölle machen. Es ist deshalb durchaus sinnvoll, boost/cstdint.hpp zu verwenden. Boost definiert darin Integer-Typen mit garantierter Größe, sodass man boost::int_least16_t schreiben kann und sich sicher sein kann, einen Typen mit mindestens 16 Bit bekommen zu haben. Falsche Typengrößen sind nur selten ein Problem, aber dank boost kann man sie gratis fast ganz vermeiden.
Der Rest der Arbeit läuft so ähnlich ab, wie als wenn man eine Library wrappt – denn etwas anderes tut man ja nicht. Das Schöne daran ist, dass man gleich ein OO-Interface über diese Funktionen legen kann. Da dies aber viel Arbeit ist, ist es oft sinnvoll etwas nur "on demand" zu wrappen (das heißt nur dann, wenn man es wirklich braucht). Stlsoft stellt dafür eine gute Anlaufstelle dar.
Wenn man für zwei oder mehr Plattformen entwickelt, wird man an verschiedenen Stellen ein Problem verschieden lösen müssen, auch wenn die Bibliotheken alle plattformunabhängig sind (wir leben ja leider nicht in einer perfekten Welt). Dann ist es wichtig, den Code nicht durch viele #ifdefs unleserlich zu machen. Eine gute Lösung hierbei ist es, für jede Plattform eine eigene Source Datei anzulegen. Dadurch hat man zwar mehr Code zu warten und man muss etwaige Bugfixes auf andere Plattformen übertragen, aber man erkauft sich dafür leichter zu lesenden Code. Denn bei vielen #ifdefs kann man leicht den Überblick verlieren, und was wohl am schlimmsten ist: auf eine neue Plattform Portieren kann unnötig kompliziert werden (weil wir schon wieder an 100.000 einzelnen Stellen den Code ändern müssen).
Um die Transparenz zu wahren, kann man Proxy-Dateien verwenden. Man erstellt pro Plattform einen eigenen Verzeichnisbaum (zum Beispiel code/programm/win32, code/programm/linux, ...) und legt an der zentralen Stelle (bei uns zum Beispiel code/programm) eine Proxy-Datei ab. Diese inkludiert lediglich die richtige Plattformdatei. Dank des Präprozessors kann man hier recht simpel #ifdefs machen, um die richtige Plattform auszuwählen. Der Clientcode bekommt davon nichts mit.
Eine Foo.cpp sieht dann in etwa so aus:
#if MY_OS == MY_WINDOWS #include "win32/Foo.cpp" #elif MY_OS == MY_LINUX #include "linux/Foo.cpp" #elif MY_OS == MY_WASANDERES #include "wasanderes/Foo.cpp" #endif
In einer zentralen Konfigurationsdatei bestimmt man dann das Betriebssystem oder lässt den Anwender das richtige #define setzen.
Der Clientcode linkt jetzt nur Foo.cpp und muss sich nicht mehr darum kümmern, ob es in Wirklichkeit win32/Foo.cpp oder linux/Foo.cpp ist.
Ein oft viel größeres Problem ist aber die Compilerunabhängigkeit. Denn auf Plattformunabhängigkeit lässt sich leicht achten, indem man alle systemabhängigen Librarys wrappt. Aber Compilerunbhängigkeit besteht meistens daraus, Compilerbugs zu umgehen. Dieses Unterfangen kann recht mühselig sein, vor allem da es kaum Ressourcen zu diesem Thema gibt.
Eine einfache Möglichkeit besteht darin, schon recht früh mit mehreren Compilern zu testen. Idealerweise lässt man hierbei die Unit Tests mit den verschiedenen Compilern laufen. Das Problem hierbei ist, dass viele Compiler nur kommerziell verfügbar sind. Die Linkliste von www.c-plusplus.net hat hier aber ein paar interessante Compilerressourcen.
Ein interessanter Link zu den Compilerunterschieden ist vielleicht auch die Dokumentation einer alten Version einer CGI/Library, die ich einmal geschrieben habe. Sie zeigt die Workarounds, die nötig waren, diese Bibliothek unter verschiedenen Compilern einzusetzen. Der Link ist aber eher für Leute, die Spaß am Basteln haben, denn wenn man unter Zeitdruck steht, dann sollte man diese Spielereien lassen und lieber konservativeren Code verwenden.
Viel tun, um sich gegen Compilerprobleme zu schützen, kann man leider nicht. Die Unittests können einem viele Probleme ersparen, da man rechtzeitig viele Inkompatibilitäten entdeckt. Oft ist es auch sinnvoll zu templatelastigen Code (vor allem Template Metaprogrammierung) zu meiden, da damit noch viele Compiler große Probleme haben. Ein großes Nein sind hier vor allem Template Template Argumente. Oft muss man leider auch das Interface ändern, um um einen Compilerbug herumzukommen. Frühes Testen kann hier viel Ärger ersparen.
Das Deployment von Crossplattform-Anwendungen ist ein nächstes großes Kapitel. Hier teilt es sich in zwei Teile auf: Bibliotheken und Anwendungen.
Bibliotheken:
Da man diese in der Regel von Source kompilieren muss (Bibliotheken in Binärform sind meistens nur dann sinnvoll, wenn man sie als DLL/SO vertreibt), muss man viele verschiedene Makefiles anbieten. wxWidgets entwickelt deshalb an bakefile, einer Möglichkeit für viele verschiedene Compiler Makefiles zu erstellen.Unter Unix kann und sollte man natürlich Autotools verwenden. Das Problem stellt sich eigentlich nur in der Windows-Welt, denn hier herrschen viele verschiedene Compiler und es existieren keine Autotools, um das Kompilieren zu vereinfachen. Andere Möglichkeiten der Distribution bieten Scons und CMake, da sie portable Wrapper um Make sind. Der Nachteil ist, dass der Anwender diese installiert haben muss.
Bei Anwendungen ist die Sache sogar viel komplizierter. Das große Problem hierbei ist, dass eine Anwendung ,die unter Windows sehr beliebt ist, unter Linux vielleicht keine Anwender findet, denn hier muss man nicht nur technische Aspekte beachten, sondern vor allem die Systemintegration. Nicht jeder BSD-Desktop hat eine "System Notification Area", sodass eine Anwendung, die sich darauf verlässt, recht schnell nicht mehr zu bedienen sein kann.
Auch andere Aspekte wie Look & Feel und sonstige Usability Guidelines unterscheiden sich von Plattform zu Plattform. Dies kann oft ein viel größeres Problem als alle technischen Gründe werden, denn wenn das Programm nicht verwendet oder gekauft wird, dann bringt die Plattformunabhängigkeit nichts. Wenn die Anwendung unter allen Plattformen gleich aussieht und sich gleich benimmt, so kann dies für User, die diese Anwendung unter mehreren Plattformen betreiben, ein Vorteil sein. Für User, die nur eine Plattform benutzen, ist dies allerdings ein Problem, denn die Anwendung sieht nicht so aus und verhält sich nicht so, wie es der User erwarten würde.
Des Weiteren kostet Plattformunabhängigkeit auch Performance. Oft ist das nicht sehr wichtig, in manchen Fällen kann es aber relevant werden. Plattformunabhängigkeit heißt im Prinzip nichts anderes als Abstraktion, und Abstraktion hat manchmal versteckte Kosten. Eine dieser Kosten ist folgendes: plattformspezifische Optimierungen. Da wir die Zielplattform nicht kennen oder nicht genau wissen, was alles Ziel werden wird, oder wir den kleinsten gemeinsamen Nenner dieser Plattformen finden müssen, nehmen wir uns die Möglichkeit speziell für diese Plattform zu optimieren.
Alles in allem ist es nicht leicht, portable Software zu entwickeln. Meistens bedeutet Plattformunabhängigkeit höhere Komplexität, schlechtere Performance, schlechtere Wartbarkeit oder nicht optimales Userinterface. Man muss immer abwägen, was wichtiger ist. Denn Portabilität ist nicht das einzige Qualitätsmerkmal einer Software und schon gar nicht das wichtigste.
-
worauf wartest du? raus damit oder willst du drei artikel gleichzeitig rausgeben?
Mr. B