extern "C"
-
Man kann in einem extern "C" Block alles formulieren, was man auch auf globaler Ebene formulieren kann. Es hat aber nur Auswirkungen auf die in diesem Block erzeugten Symbole für den Linker. Code in diesen Abschnitten wird wie normaler C++-Code übersetzt.
EDIT: Eine Ausnahme gibt es dort, wo mit extern "C" identische Symbole durch Funktionsüberladung entstehen würden, die ohne extern "C" nicht entstehen würden.
-
LordJaxom schrieb:
Es hat aber nur Auswirkungen auf die in diesem Block erzeugten Symbole für den Linker. Code in diesen Abschnitten wird wie normaler C++-Code übersetzt.
Das stimmt nicht, die Aufrufkonventionen entsprechen denen der C ABI der jeweiligen Plattform, diese muß nicht identisch mit denen von C++ sein. Da Thema ist wichtig im Zusammenhang mit Callback-Funktionen für C-APIs, diese müssen mit "extern C" übersetzt werden, weil es sonst nicht garantiert ist, daß die Aufrufkonventionen übereinstimmen.
-
Wann macht extern "C" Sinn? Hat jemand ein Beispiel
-
~john hat doch ein Beispiel gebracht.
-
/* C-Programm */ int myfunc(double, float); int main(void) { int x = myfunc(12.5, 16.3); } /* C++-Programm */ extern "C" /* ohne würde der Linker das myfunc im obigen Programm nicht finden */ int myfunc(double a, float b) { ... }/* C++-Programm */ extern "C" /* ohne würde mythreadfunc evtl. andere Aufrufkonventionen haben, als pthread_create (eine C-Funktion) sie erwartet */ void mythreadfunc( void* ) { ... } int main() { pthread_create( &thread, &threadattr, mythreadfunc, 0 ); }
-
Zweites Beispiel hab ich verstanden.
Warum wird er es im 1. Beispiel nicht finden?
-
Was ich herausgefunden habe ist, das man Prototypen und Quelltext mit extern "C" klammern muss, sonst gibt es Kompilerfehler wie Externen Symbol nicht gefuden oder Bindungsangaben wiedersprechen sich
-
-
Sisko schrieb:
Zweites Beispiel hab ich verstanden.
Warum wird er es im 1. Beispiel nicht finden?Das Problem entsteht beim Linken. Der Linker sucht in ein einzelnen, kompilierten Modulen nach den benötigten Funktionsreferenzen.
C und C++ haben aber unterschiedliche Mechanismen, um diese Funktionsreferenzen darzustellen. Wenn Du das extern "C" weglässt, dann baut der Compiler C++ Aufrufe ein.
Beispiel:
Du hast ein aufrufendes Modul mit C++ Aufrufkonvention (extern "C" vergessen). Im aufzurufenden Modul wurde aber die C Konvention (weil es vielleicht eine lib aus einem C-Compiler ist) benutzt. Das führt dazu, dass der Linker die Referenzen auf die Funktionen des aufzurufenden Moduls nicht findet, und Du bekommst einen Linker-Fehler.
-
Sisko schrieb:
Was ich herausgefunden habe ist, das man Prototypen und Quelltext mit extern "C" klammern muss, sonst gibt es Kompilerfehler wie Externen Symbol nicht gefuden oder Bindungsangaben wiedersprechen sich
der prototyp in einer headerdatei wird auch häufig mit
#ifdef __cplusplus extern "C" { #endif int f(); #ifdef __cplusplus } #endifeingeklammert, damit auch das kompilieren mit c keine probleme macht. das widerspricht aber afaik dem c-standard.
-
Das 1. Beispiel geht nur wenn das C Programm vorher schon kompiliert vorliegt in einer lib oder dll
-
Sisko schrieb:
Das 1. Beispiel geht nur wenn das C Programm vorher schon kompiliert vorliegt in einer lib oder dll
Das erste Beispiel "geht", wenn die als "C-Programm" überschriebene Quelldatei mit einem C-Compiler übersetzt wird.
-
Wenn ich jetzt eine C-Programm habe und möchte einen Teil davon in einem C++ Programm verwenden, dann nimm ich mir den Kompilierte Teil (die *.obj Datei?)
und setze die in mein C++ Projekt ein?
So hab ich das verstanden.