Szukaj…


Wprowadzenie

Specyfikacja powiązań mówi kompilatorowi, aby kompilował deklaracje w sposób, który pozwala na połączenie ich z deklaracjami napisanymi w innym języku, takim jak C.

Składnia

  • extern string-literal { deklaracja-seq ( opt )}
  • zewnętrzna deklaracja dosłowna

Uwagi

Standard wymaga, aby wszystkie kompilatory obsługiwały extern "C" , aby umożliwić C ++ zgodność z C, oraz extern "C++" , która może być użyta do zastąpienia załączonej specyfikacji powiązania i przywrócenia domyślnej. Inne obsługiwane specyfikacje powiązań są zdefiniowane w implementacji .

Procedura obsługi sygnałów dla systemu operacyjnego typu Unix

Ponieważ jądro wywołuje procedurę obsługi sygnału za pomocą konwencji wywoływania C, musimy poinformować kompilator, aby używał konwencji wywoływania C podczas kompilacji funkcji.

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

Dostosowanie nagłówka biblioteki C do C ++

Nagłówek biblioteki AC można zwykle włączyć do programu C ++, ponieważ większość deklaracji jest poprawna zarówno w C, jak i C ++. Rozważmy na przykład następujący foo.h :

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

Definicja make_foo jest oddzielnie kompilowana i dystrybuowana wraz z nagłówkiem w formie obiektowej.

Program w C ++ może #include <foo.h> , ale kompilator nie będzie wiedział, że funkcja make_foo jest zdefiniowana jako symbol C i prawdopodobnie spróbuje poszukać go ze zniekształconą nazwą i nie uda się go zlokalizować. Nawet jeśli może znaleźć definicję make_foo w bibliotece, nie wszystkie platformy używają tych samych konwencji wywoływania dla C i C ++, a kompilator C ++ użyje konwencji wywoływania C ++ podczas wywoływania make_foo , co może spowodować błąd segmentacji, jeśli make_foo oczekuje, że zostanie wywołany zgodnie z konwencją wywoływania C.

Rozwiązaniem tego problemu jest zawinięcie prawie wszystkich deklaracji w nagłówku w extern "C" bloku 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

Teraz, gdy foo.h jest dołączony z programu C, będzie wyglądał jak zwykłe deklaracje, ale kiedy foo.h zostanie dołączony z programu C ++, make_foo będzie znajdować się w extern "C" bloku extern "C" , a kompilator będzie wiedział, że szuka niezmienioną nazwę i użyj konwencji wywoływania C.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow