2016-04-22 7 views
6

Per utilizzare il codice C++ in un file C, ho letto che possiamo fare semplicemente extern "C" { (where the c++ code goes here)}, ma quando provo a stampare qualcosa usando cout, continuo a ricevere un errore perché non riconosce la libreria. Penso di essere solo confuso su come la "C" esterna ti permette di usare il codice C++ in C.in che modo la "C" esterna consente il codice C++ in un file C?

risposta

12

È vero il contrario. Puoi usare extern C per aggiungere il codice che vuoi compilare come codice C usando un compilatore C++.

A meno che non manchi qualcosa, non è possibile compilare codice C++ con un compilatore C.

9

Il costrutto extern "C" è una sintassi specifica per C++, nessun compilatore C lo capirà.

Ecco perché sarà quasi sempre vederlo in coppia con qualche conditional compilation come

#ifdef __cplusplus 
extern "C" { 
#endif 
... 
#ifdef __cplusplus 
} 
#endif 

Cosa extern "C"fa è semplicemente quello di inibire name mangling il che significa che i simboli definiti in un C++ file sorgente può essere utilizzato in un programma C.

Ciò consente di avere un progetto con sorgenti miste C e C++ e la sorgente C può chiamare le funzioni C++ che sono state definite come extern "C".

Molto semplice, e stupido, ad esempio solo per mostrare il punto:

consente di dire che abbiamo un file sorgente C, compilato con un compilatore C:

#include <stdio.h> 

void foo(void); // Declare function prototype, so it can be called 

int main(void) 
{ 
    printf("Calling foo...\n"); 
    foo(); 
    printf("Done\n"); 

    return 0; 
} 

allora abbiamo un C file sorgente ++ per la funzione foo: file sorgente

#include <iostream> 

extern "C" void foo() 
{ 
    std::cout << "Hello from foo\n"; 
} 

la C è compilato con un compilatore C, e il file di origine C++ è compilato con un compilatore C++. Quindi i due file oggetto sono collegati insieme per formare il programma eseguibile. Poiché foo è stato definito come extern "C", il nome del simbolo nel file oggetto non viene alterato e il linker può risolvere il riferimento dal file oggetto creato dal compilatore C.

Funziona anche nell'altra direzione. Poiché i simboli in C non vengono alterati, il compilatore C++ deve saperlo, e ciò viene fatto dichiarando i simboli C extern "C", di solito in un file di intestazione usando la compilazione condizionale come mostrato sopra. Se non fosse usato extern "C", il compilatore C++ penserebbe che i simboli fossero simboli C++ e maneggia i nomi che portano a problemi di linker quando il linker non riesce a trovare i simboli storti.

Altrettanto stupido esempio: In primo luogo un file sorgente C++

#include <iostream> 

extern "C" void bar(); // Declare function prototype as an unmangled symbol 

int main() 
{ 
    std::cout << "Calling bar...\n"; 
    bar(); 
} 

Poi il file sorgente C

#include <stdio.h> 

void bar(void) 
{ 
    printf("Inside bar\n"); 
} 
+2

C'è un po 'più di "extern" C "' di inibire il nome mangling. Fa anche altre cose per consentire l'interfacciamento tra C e C++. – Peter

0

extern "C" è un modo di mettere il codice C nel codice C++. Più specificamente dice al compilatore di disabilitare alcune cose come l'overloading delle funzioni in modo che possa anche disattivare il nome mangling.In una semplice funzione come C++:

int add(int a, int b) { 
    return a+b; 
} 

effettivamente ottenere qualche nome funky nella libreria per indicare i parametri in modo che se si definisce un'altra funzione come:

double add(double a, double b) { 
    return a+b; 
} 

che sa che uno di chiamare . Non lo vuoi se stai cercando di usare una libreria C ed è per questo che è extern "C". Tutto ciò detto, extern "C" non consente C++ in un programma C.

0

I simboli C++ esportati, come generato il mio compilatore, sono manglessi per includere ulteriori informazioni sul tipo del simbolo sul linker.

Così le seguenti funzioni sovraccarichi sarebbero distinguibili dal linker in C++, ma non C:

  • int fn();
  • int fn(int);
  • int fn(char*);
  • int fn(char*) const;
  • int fn(const char*);

Il extern "C" { ... } sintassi permette simboli (o riferimenti a simboli C) per essere definiti in codice C++ senza utilizzare i mangling regole. Ciò consente di collegare tale codice C++ alle librerie C.