2015-03-11 23 views
12
namespace someNameSpace { 
    extern "C" void doSomething() 
     { 
      someOperations(); 
     } 
} 

Voglio eseguire doSomething() in ambiente C++ e C.Collegamento "C" extern all'interno dello spazio dei nomi C++?

È someNameSpace che incapsula ancora doSomething() se lo espongo al collegamento extern "C"?

C'è un buon modo per condividere le funzioni tra C++ e C evitando lo spazio dei nomi globale inquinante sul lato C++?

Edit: Perché questo codice viene utilizzato principalmente in C++ modalità, mentre il collegamento C è per uso di prova solo, credo che questo sia un modo migliore per farlo.

namespace someNameSpace { 
    #ifdef COMPILE_FOR_C_LINKAGE 
    extern "C" 
    #else 
    extern "C++" 
    #endif 
    { 
     void doSomething() 
      { 
       someOperations(); 
      } 
    } 
} 
+0

Hai provato a usarlo in un programma C? Se è così, cosa è successo? –

+0

@RyanJ Sì, ho provato, si compila e si collega bene sia in C++ che in C. Non l'ho ancora eseguito. – user3528438

risposta

10

Il codice funziona, ma si dovrebbe stare attenti che tutte le funzioni che hanno extern "C" linkage condividono lo stesso spazio di nomi, ma che non deve essere confuso con la nozione C++ di "spazio dei nomi": La vostra funzione è davvero someNameSpace::doSomething , ma non è possibile avere altre funzioni extern "C" con nome non qualificato doSomething in qualsiasi altro spazio dei nomi.

Vedere 7.5/6:

Al massimo una funzione con un nome particolare può avere il linguaggio C linkage. Due dichiarazioni per una funzione con collegamento di linguaggio C con lo stesso nome di funzione (ignorando i nomi di spazio dei nomi che lo qualificano) che appaiono in ambiti di spazio dei nomi diversi fanno riferimento alla stessa funzione. Due dichiarazioni per una variabile con il collegamento di linguaggio C con lo stesso nome (ignorando i nomi dello spazio dei nomi che lo qualificano) che appaiono in diversi ambiti dello spazio dei nomi si riferiscono alla stessa variabile. Un'entità con collegamento linguaggio C non deve essere dichiarata con lo lo stesso nome di una variabile nell'ambito globale, a meno che entrambe le dichiarazioni denotino la stessa entità; nessuna diagnostica è richiesta se le dichiarazioni sono visualizzate in diverse unità di traduzione. Una variabile con collegamento linguistico C non deve essere dichiarata con lo stesso nome di una funzione con linking linguaggio C ( qualifica i rispettivi nomi) ; non è richiesta alcuna diagnostica se le dichiarazioni appaiono in diverse unità di conversione . [Nota: nel programma viene visualizzata solo una definizione per un'entità con un nome specifico con collegamento linguaggio C (vedere 3.2); ciò implica che tale entità non deve essere definita in più di uno spazio nomi . - nota end]

vostro arbitri di stile globali del progetto dell'azienda o dovrebbe essere in grado di consigliarvi su un criterio di denominazione adatto per il vostro codice di base.

+0

Un'entità con collegamento linguaggio C non deve essere dichiarata con lo stesso nome di una variabile nell'ambito globale, a meno che entrambe le dichiarazioni denotino la stessa entità; ---- Si tratta di un'istruzione "entità vs variabile"? Ho sperimentato con g ++ 4.3.3 e sembra vero.Il conflitto si verifica solo quando dichiaro nuovamente una variabile globale come "extern int doSomething = 1;" ma va bene se definisco un altro "extern void doSomething() {}" a patto che non sia un altro collegamento C esterno. – user3528438

+1

L'istruzione finale nel primo paragrafo è errata: è possibile avere un altro 'doSomething 'definito in qualche altro spazio dei nomi, purché non sia" extern "C" '. –

+0

@ChrisDodd: Ah sì, questo è quello che intendevo. Modificato. Grazie! –

2

Solo pezzo di codice per illustrare il comportamento stabilite da Kerrek SB risposta

#include <iostream> 

namespace C{ 
    void Hello(){ 
     std::cout<<"Hello"<<std::endl; 
    } 
    extern "C" void HelloThere(){ 
     std::cout<<"Hello There from extern \"C\""<<std::endl; 
    } 
} 

extern "C" void HelloThere(); 

int main() { 
    C::Hello(); 
    C::HelloThere(); //Compiles 
    //Hello(); <--- does not compile 
    HelloThere(); //Also compiles and prints the same as C::HelloThere() !!! 

    return 0; 
} 

Live at http://ideone.com/X26wfR

Problemi correlati