Ricerca…


introduzione

Una specifica di collegamento indica al compilatore di compilare le dichiarazioni in un modo che consenta loro di essere collegate insieme alle dichiarazioni scritte in un'altra lingua, come ad esempio C.

Sintassi

  • extern string-literal { declaration-seq ( opt )}
  • dichiarazione extern stringa-letterale

Osservazioni

Lo standard richiede che tutti i compilatori supportino l' extern "C" per consentire a C ++ di essere compatibile con C e extern "C++" , che può essere utilizzato per sovrascrivere una specifica di linkage e ripristinare l'impostazione predefinita. Altre specifiche del collegamento supportate sono definite dall'implementazione .

Gestore del segnale per sistema operativo Unix-like

Poiché un gestore di segnale verrà chiamato dal kernel usando la convenzione di chiamata C, dobbiamo dire al compilatore di usare la convenzione di chiamata C durante la compilazione della funzione.

volatile sig_atomic_t death_signal = 0;
extern "C" void cleanup(int signum) {
    death_signal = signum;
}
int main() {
    bind(...);
    listen(...);
    signal(SIGTERM, cleanup);
    while (int fd = accept(...)) {
        if (fd == -1 && errno == EINTR && death_signal) {
            printf("Caught signal %d; shutting down\n", death_signal);
            break;
        }
        // ...
    }
}

Creare un'intestazione di libreria C compatibile con C ++

L'intestazione della libreria AC può essere generalmente inclusa in un programma C ++, poiché la maggior parte delle dichiarazioni sono valide sia in C che in C ++. Ad esempio, si consideri il seguente foo.h :

typedef struct Foo {
    int bar;
} Foo;
Foo make_foo(int);

La definizione di make_foo viene compilata e distribuita separatamente con l'intestazione in forma di oggetto.

Un programma C ++ può #include <foo.h> , ma il compilatore non saprà che la funzione make_foo è definita come un simbolo C e probabilmente cercherà di cercarla con un nome make_foo e non riuscirà a make_foo . Anche se riesce a trovare la definizione di make_foo nella libreria, non tutte le piattaforme utilizzano le stesse convenzioni di chiamata per C e C ++ e il compilatore C ++ utilizzerà la convenzione di chiamata C ++ quando chiama make_foo , il che probabilmente causerà un errore di segmentazione se make_foo si aspetta di essere chiamato con la convenzione di chiamata C.

Il modo per ovviare a questo problema è quello di racchiudere quasi tutte le dichiarazioni nell'intestazione in un blocco extern "C" .

#ifdef __cplusplus
extern "C" {
#endif

typedef struct Foo {
    int bar;
} Foo;
Foo make_foo(int);

#ifdef __cplusplus
}  /* end of "extern C" block */
#endif

Ora quando foo.h è incluso da un programma C, apparirà semplicemente come dichiarazioni ordinarie, ma quando foo.h è incluso in un programma C ++, make_foo si troverà all'interno di un blocco extern "C" e il compilatore saprà di cercare un nome senza maglie e usa la convenzione di chiamata C.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow