Suche…


Einführung

Eine Verknüpfungsspezifikation weist den Compiler an, Deklarationen so zu kompilieren, dass sie mit Deklarationen verknüpft werden können, die in einer anderen Sprache wie C geschrieben sind.

Syntax

  • externes String-Literal { Deklaration-Seq ( Opt )}
  • externe String-Literal- Deklaration

Bemerkungen

Der Standard verlangt, dass alle Compiler extern "C" , damit C ++ mit C und extern "C++" kompatibel ist, was dazu verwendet werden kann, eine umschließende Verbindungsspezifikation zu überschreiben und den Standard wiederherzustellen. Andere unterstützte Verbindungsspezifikationen sind implementierungsdefiniert .

Signalhandler für ein Unix-ähnliches Betriebssystem

Da vom Kernel ein Signalhandler mit der C-Aufrufkonvention aufgerufen wird, muss der Compiler beim Compilieren der Funktion aufgefordert werden, die C-Aufrufkonvention zu verwenden.

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

Einen C-Bibliotheksheader mit C ++ kompatibel machen

AC-Bibliotheksheader können normalerweise in ein C ++ - Programm eingefügt werden, da die meisten Deklarationen sowohl in C als auch in C ++ gültig sind. Betrachten Sie zum Beispiel folgendes foo.h :

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

Die Definition von make_foo wird separat zusammengestellt und mit dem Header in Objektform verteilt.

Ein C ++ - Programm kann #include <foo.h> , der Compiler weiß jedoch nicht, dass die Funktion make_foo als C-Symbol definiert ist, und versucht wahrscheinlich, es mit einem entstellten Namen zu suchen und kann es nicht finden. Selbst wenn die Definition von make_foo in der Bibliothek gefunden werden kann, verwenden nicht alle Plattformen die gleichen Aufrufkonventionen für C und C ++, und der C ++ - Compiler verwendet beim Aufruf von make_foo die C ++ - Aufrufkonvention, die bei make_foo wahrscheinlich zu einem Segmentierungsfehler make_foo erwartet, mit der C-Aufrufkonvention aufgerufen zu werden.

Um dieses Problem zu beheben, können Sie fast alle Deklarationen im Header in einen extern "C" -Block 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

Wenn nun foo.h aus einem C-Programm enthalten ist, wird es nur als gewöhnliche Deklaration foo.h Wenn jedoch foo.h aus einem C ++ - Programm enthalten ist, befindet sich make_foo in einem extern "C" -Block, und der Compiler weiß zu suchen einen unveränderten Namen und verwenden Sie die C-Aufrufkonvention.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow