| Zeile 163: | Zeile 163: | ||
Exceptions sollten auch am besten innerhalb des Kernels deaktiviert werden. Mit g++ können Exceptions über den Kommandozeilenparameter ''-fno-exceptions'' deaktiviert werden. | Exceptions sollten auch am besten innerhalb des Kernels deaktiviert werden. Mit g++ können Exceptions über den Kommandozeilenparameter ''-fno-exceptions'' deaktiviert werden. | ||
| − | == C++ Funktionen aus C/Assembler nutzen == | + | == sonstige Probleme == |
| + | === C++ Funktionen aus C/Assembler nutzen === | ||
Um C++ Funktionen von Sourcecode, der in C oder Assembler geschrieben ist, aufrufen zu können, muss das ''name mangling'' - dabei werden die Funktionsnamen nicht direkt als Symbolnamen genommen, sondern Parameter- und Rückgabetypen und Informationen zum Namespace mit in den Symbolnamen eingebaut - deaktivieren für diese Funktion. Dies geschieht dadurch, dass die betreffende Funktion innerhalb des C++-Sourcecodes ''extern "C"'' deklariert wird, wie in folgendem Beispiel: | Um C++ Funktionen von Sourcecode, der in C oder Assembler geschrieben ist, aufrufen zu können, muss das ''name mangling'' - dabei werden die Funktionsnamen nicht direkt als Symbolnamen genommen, sondern Parameter- und Rückgabetypen und Informationen zum Namespace mit in den Symbolnamen eingebaut - deaktivieren für diese Funktion. Dies geschieht dadurch, dass die betreffende Funktion innerhalb des C++-Sourcecodes ''extern "C"'' deklariert wird, wie in folgendem Beispiel: | ||
<cpp> | <cpp> | ||
| Zeile 169: | Zeile 170: | ||
</cpp> | </cpp> | ||
Anschließend kann die Funktion in C++ ganz normal definiert werden und schließlich aus dem C/Assembler-Sourcecode heraus wie sonst üblich aufgerufen werden. | Anschließend kann die Funktion in C++ ganz normal definiert werden und schließlich aus dem C/Assembler-Sourcecode heraus wie sonst üblich aufgerufen werden. | ||
| + | |||
| + | === TODO === | ||
| + | Das Problem hier ist, dass C++ im Gegensatz zu C keine TODO unterstützt, beispielsweise wird der Code | ||
| + | <cpp> | ||
| + | struct | ||
| + | { | ||
| + | uint16_t limit; | ||
| + | void* pointer; | ||
| + | } __attribute__((packed)) gdtp = | ||
| + | { | ||
| + | .limit = GDT_ENTRIES * 8 - 1, | ||
| + | .pointer = gdt, | ||
| + | }; | ||
| + | </cpp> | ||
| + | beim Kompilieren eine Fehlermeldung namens ''expected primary-expression before ‘.’ token'' ausgeben. | ||
| + | |||
| + | Man kann allerdings den gleichen Effekt entweder durch Weglassen des Feldnamens erreichen (dann muss die Initialisierung in der Reihenfolge wie die Definition des Strukturtyps sein): | ||
| + | <cpp> | ||
| + | struct | ||
| + | { | ||
| + | uint16_t limit; | ||
| + | void* pointer; | ||
| + | } __attribute__((packed)) gdtp = | ||
| + | { | ||
| + | GDT_ENTRIES * 8 - 1, | ||
| + | gdt, | ||
| + | }; | ||
| + | </cpp> | ||
| + | Die andere Möglichkeit ist einen Konstruktor für die Struktur zu definieren - dafür muss aber die Struktur benannt werden: | ||
| + | <cpp> | ||
| + | struct gdt_register | ||
| + | { | ||
| + | uint16_t limit; | ||
| + | void* pointer; | ||
| + | |||
| + | gdt_register(uint16_t _limit, | ||
| + | void* _pointer) | ||
| + | : limit(_limit), pointer(_pointer){} | ||
| + | } __attribute__((packed)); | ||
| + | |||
| + | gdt_register gdtp(GDT_ENTRIES * 8 - 1, gdt); | ||
| + | </cpp> | ||
== Siehe auch == | == Siehe auch == | ||