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