C++
Kopplingsspecifikationer
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.