Kann mir jemand folgendes genauer erklären?



  • #ifdef __cplusplus
    extern "C" { // was bedeutet diese zeile denn überhaupt?
    #endif
    

    versteht es nicht! kann mir das jemand erlären, was man damit erreichen kann?



  • Das bedeutet, dass in diesem Bereich (extern "C" { ... }) die C-Regeln für das Linken gelten. AFAIK ist das notwendig, wenn du C-Libs, die von einem C-Compiler kompiliert wurden in deinen Programmen verwendest, da sich die finalen Namen in C und C++ unterscheiden (bei letzterem gehört meist auch die Signatur und der Namespace zum Namen).



  • Ich versuch mich auch mal mit einer erklärung:

    wenn der c-compiler eine funktion, sagen wir mal:

    int funktion(int);
    

    compiliert, dann erzeugt er maschinencode für die funktion und speichert ihn in der objektdatei unter dem namen der funktion. wenn der compiler dann irgendwo einen aufruf für eine funktion findet, dann sucht er in den objektdateien/libs, die er in der befehlszeile bekommen hat nach einem eintrag des funktionsnamens und setzt den code ein (ist jetzt natürlich *grob* vereinfacht dargestellt).

    bei c++ gibts mit diesem system aber ein problem: in c++ kann man nämlich verschiedene funktionen des selben namens definieren:

    int funktion(int);
    int funktion(double);
    

    die würdrn dann beide unter dem selben namen in der objektdatei stehen. bei einem aufruf einer dieser funktionen wüsste der compiler dann nicht welche er nehmen soll.

    deshalb erzeugt der c++-compiler für jede funktion intern einen kryptischen funktionsnamen, der auch informationen über die parametertypen enthält. damit werden die namen der funktionen wieder eindeutig:

    funktion@@YAHH@Z
    funktion@@YAHN@Z
    

    nun gibts aber wieder ein problem: wurde die funktion mit einen c-compiler compiliert und soll mit einem c++-programm gelinkt werden, dann klapps wieder nicht. denn der c-compiler hat die funktion unter dem namen "funktion" gespeichert, der c++-compiler sucht sie aber unter dem namen "funktion@@YAHH@Z". un das gibt einen linker-fehler.

    deshalb gibt es

    extern "C"
    {
      // c-funktions-prototypen
    }
    

    dies weist den c++-compiler an, für alle funktionen, deren prototypen innerhalb von extern "C" stehen, die c-namenskonvention zu verwenden anstelle der sonst in c++ üblichen kryptischen namen. damit kann man dann mit einem c-compiler compilierte funktionen mit einem c++-programm linken.

    alle ansi-c-standardfunktionen, die es auch in c++ gibt, wie printf(), strcpy() etc sind in den headern inerhalb eines extern "C" deklariert.

    das

    #ifndef __cplusplus
    #endif
    

    drumrum braucht es, weil die selben header-dateien auf von c-compilern verwendet werden und c kennt extern "C" nicht. c++-compiler definieren immer das macro __cplusplus. das ist mw standard.



  • Man erreicht damit auch, dass sich auf der Seite der C++ Programmierer ein Schlendrian einschleicht, da sie C Header nicht mehr innerhalb von 'extern "C"' sondern direkt einbinden.


Anmelden zum Antworten