Was ist das: extern "C"



  • Hi,

    ich habe jetzt schon sehr sehr oft folgendes gesehen:

    extern "C" void meine_funktion ()
    {
        // mach was
    }
    
    // -----
    
    extern "C" int _fldused = 0;
    
    // -----
    
    extern "C" void irgendeine_funktion_die_in_ner_lib_implementiert_wurde ();
    

    Meine Frage ist nun: Wofür ist das, wieso benutzt man das, warum benutzt man das und was kann man damit alles machen? 🙂

    Danke euch im voraus 🙂



  • extern "C" schaltet die Namenszerstückelung aus. Damit kannst du auf Funktionen aus einen C-Bibliothek zugreifen bzw. deine Funktione von C aus aufrufbar machen.



  • Was für eine Namenszerstückelung und wieso sollte ich die aus C aufrufbar machen, wenns doch eigentlich C ist?!

    nimms mir nicht übel, aber irgendwie ist mir das noch viel zu allgemein und unverständlich 😮



  • Hmm ... es ist eher die Frage wie das aussieht wenn du dir es in Assembly anguckst ^^ Dann wird es sonnst lustig, wenn du einen C++-Compiler nimmst und Funktionen die dabei rauskommen dann in einem Assembly-Code nutzen willst 😃 Gibt da nämlich keine einheitliche Norm, wie der Compiler die Funktionen aussehen lassen soll ... MSVC++ macht bsw. da andere Sachen als der GXX ...



  • Mojon schrieb:

    Was für eine Namenszerstückelung und wieso sollte ich die aus C aufrufbar machen, wenns doch eigentlich C ist?!

    nimms mir nicht übel, aber irgendwie ist mir das noch viel zu allgemein und unverständlich 😮

    Das war eigentlich ziemlich präziese, unverständlich vielleicht für dich 😉

    Die sache ist, dass C++ die Funktionen in den Objektdateien (.o oder .obj) anders benennt, als C. Wenn du extern "C" verwendest, benutzt der Compiler die C Namensgebung der Funktionen.



  • Okay, aber was für einen Effekt hat das bei Variablen?



  • Mojon schrieb:

    Okay, aber was für einen Effekt hat das bei Variablen?

    anscheinend gibt es auch einen "Mangled Name" für Variablen in C++



  • Vertexwahn schrieb:

    Mojon schrieb:

    Okay, aber was für einen Effekt hat das bei Variablen?

    anscheinend gibt es auch einen "Mangled Name" für Variablen in C++

    Die Namensräume werden ebenfalls einkodiert.



  • Gibt es dazu irgendwo weiterführende Links? Nehmt es mir nicht übel, aber was hier gesagt wurde reicht mir nicht aus, es ist mir alles nicht konkret bzw. stichhaltig genug.



  • void foo();
    void foo(int);
    namespace Bar { void foo(); }
    class Baz { void foo(); }
    

    Diese foos wollen in C++ alle unterschieden werden. Also nennt der Compiler sie um in kryptischere, implementationsabhängige Namen (Stichwort: Name Mangling). In C gabs das nicht, da konnten die Funktionen einfach ihren Namen behalten. Wenn du nun C-Code in C++ benutzen willst, verträgt ers nicht, wenn die Namen verändert werden. Deshalb sagt man dem Compiler mit extern "C" , dass er die Namen doch bitte so lassen soll, wie sie sind.



  • http://en.wikipedia.org/wiki/Name_mangling

    war übrigens der erste beitrag bei google...



  • Michael E. schrieb:

    void foo();
    void foo(int);
    namespace Bar { void foo(); }
    class Baz { void foo(); }
    

    Diese foos wollen in C++ alle unterschieden werden. Also nennt der Compiler sie um in kryptischere, implementationsabhängige Namen (Stichwort: Name Mangling). In C gabs das nicht, da konnten die Funktionen einfach ihren Namen behalten. Wenn du nun C-Code in C++ benutzen willst, verträgt ers nicht, wenn die Namen verändert werden. Deshalb sagt man dem Compiler mit extern "C" , dass er die Namen doch bitte so lassen soll, wie sie sind.

    Also wenn ich das richtig verstehe würde folgendes nicht gehen:

    extern "C" void foo (void) 
    { printf ("%s", __FUNCTION__); }
    
    extern "C" void foo (int wert) 
    { printf ("%s:%d", __FUNCTION__, wert); }
    

    Da es in C keine Funktionsüberladung oder sonstige Polymorphie gab?



  • [quote="Mojon"]

    Michael E. schrieb:

    void foo();
    vwenn ich das richtig verstehe würde folgendes nicht gehen:
    
    [cpp]
    extern "C" void foo (void) 
    { printf ("%s", __FUNCTION__); }
    
    extern "C" void foo (int wert) 
    { printf ("%s:%d", __FUNCTION__, wert); }
    

    Da es in C keine Funktionsüberladung oder sonstige Polymorphie gab?

    genau - das sollte laut dem Wikipedia Artikel nicht funktionieren... (allerdings sollte man da vorsichtig sein - Der C Standard entwickelt sich auch weiter - da wurde z. B. der Datentyp bool eingeführt, usw. ich kann mir auch vorstellen das da entzwischen auch schon Polymorphie für Funktionen eingeführt wurde...)


Anmelden zum Antworten