2009-08-18 8 views
20

Eventuali duplicati:
Why do we need extern “C”{ #include <foo.h> } in C++?Quando utilizzare extern "C" in C++?

Ho visto spesso programmi codificati come:

extern "C" bool doSomeWork() { 
    // 
    return true; 
} 

Perché utilizziamo un blocco extern "C"? Possiamo sostituirlo con qualcosa in C++? C'è qualche vantaggio nell'uso di extern "C"?

Vedo un collegamento che spiega this ma perché abbiamo bisogno di compilare qualcosa in C quando abbiamo già C++?

+3

Duplicato di http://stackoverflow.com/questions/67894/why-do-we-need-extern-c-include-foo-h-in-c – Aamir

+0

correlati: http://stackoverflow.com/questions/1041866/extern-c http://stackoverflow.com/questions/717729/does-extern-c-have-any-effect-in-c http://stackoverflow.com/questions/496448/how-to-correctly -use-the-extern-keword-in-c / –

risposta

29

extern "C" rende i nomi non mutilati.

E 'usato quando:

  1. Abbiamo bisogno di utilizzare qualche libreria C in C++

    extern "C" int foo(int); 
    
  2. Abbiamo bisogno di esportare un po' di codice C++ a C

    extern "C" int foo(int) { something; } 
    
  3. Abbiamo bisogno una capacità di risolvere il simbolo nella libreria condivisa - quindi dobbiamo liberarci della maneggevolezza

    extern "C" int foo(int) { something; } 
    /// 
    typedef int (*foo_type)(int); 
    foo_type f = (foo_type)dlsym(handle,"foo") 
    
10

Un luogo dove extern "C" ha senso è quando si sta collegando a una libreria che è stato compilato come codice C.

extern "C" { 
    #include "c_only_header.h" 
} 

In caso contrario, si potrebbe ottenere errori del linker perché la libreria contiene le funzioni con C-linkage (_myfunc), ma il compilatore C++, che ha esaminato l'intestazione della biblioteca come codice C++, generato ++ nomi dei simboli C per le funzioni (" _myfunc @ XAZZYE "- questo è chiamato mangling e diverso per ogni compilatore).

Un altro punto in cui viene utilizzata la "C" esterna serve a garantire il collegamento C anche per le funzioni scritte in C++, ad es.

extern "C" void __stdcall PrintHello() { 
    cout << "Hello World" << endl; 
} 

Tale funzione può essere esportato in una DLL e sarà quindi richiamabile da un altro linguaggio di programmazione in quanto la compilazione non storpiare il suo nome. Se hai aggiunto un altro overload della stessa funzione, ad es.

extern "C" void __stdcall PrintHello() { 
    cout << "Hello World" << endl; 
} 
extern "C" void __stdcall PrintHello(const char *name) { 
    cout << "Hello, " << name << endl; 
} 

maggior parte dei compilatori sarebbe poi prendere questo, e quindi impedire l'utilizzo sovraccarichi funzionali nel proprio funzioni DLL-pubblico.