Sök…


Introduktion

En kopplingsspecifikation säger kompilatorn att sammanställa deklarationer på ett sätt som gör att de kan kopplas samman med deklarationer skrivna på ett annat språk, till exempel C.

Syntax

  • extern strängbokstavlig { deklaration-seq ( opt )}
  • extern strängbokstavlig deklaration

Anmärkningar

Standarden kräver att alla kompilatorer stöder extern "C" för att tillåta C ++ att vara kompatibel med C, och extern "C++" , som kan användas för att åsidosätta en bifogad kopplingsspecifikation och återställa standardvärdet. Andra stödd länkspecifikationer är implementeringsdefinerade .

Signalhanterare för Unix-liknande operativsystem

Eftersom en signalhanterare kommer att anropas av kärnan med hjälp av C-samtalskonventionen, måste vi säga kompilatorn att använda C-samtalskonventionen när man kompilerar funktionen.

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;
        }
        // ...
    }
}

Att göra en C-biblioteksrubrik kompatibel med C ++

AC-bibliotekshuvud kan vanligtvis inkluderas i ett C ++ -program, eftersom de flesta deklarationer är giltiga i både C och C ++. Tänk till exempel på följande foo.h :

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

Definitionen av make_foo kompileras separat och distribueras med rubriken i objektform.

Ett C ++ -program kan #include <foo.h> , men kompilatorn vet inte att make_foo funktionen är definierad som en C-symbol och kommer förmodligen att försöka leta efter den med ett skiftat namn och misslyckas med att hitta den. Även om den kan hitta definitionen av make_foo i biblioteket, använder inte alla plattformar samma samtalskonventioner för C och C ++, och C ++ -kompileraren kommer att använda C ++- make_foo när man ringer make_foo , vilket sannolikt kommer att orsaka ett segmenteringsfel om make_foo förväntar sig att kallas med C-samtalskonventionen.

Sättet att avhjälpa detta problem är att förpacka nästan alla deklarationer i rubriken i ett extern "C" -block.

#ifdef __cplusplus
extern "C" {
#endif

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

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

När foo.h ingår från ett C-program kommer det bara att visas som vanliga deklarationer, men när foo.h ingår från ett C ++ -program kommer make_foo att vara i ett extern "C" -block och kompilatorn vet att man letar efter ett obemannat namn och använd C-samtalskonventionen.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow