C++
Especificaciones de vinculación
Buscar..
Introducción
Una especificación de vinculación le dice al compilador que compile las declaraciones de una manera que les permita vincularse con declaraciones escritas en otro idioma, como C.
Sintaxis
- cadena-literal externa { declaración-seq ( opt )}
- declaración cadena-literal externa
Observaciones
El estándar requiere que todos los compiladores admitan la extern "C"
para permitir que C ++ sea compatible con C, y la extern "C++"
, que se puede usar para anular una especificación de enlace adjunto y restaurar la predeterminada. Otras especificaciones de enlace soportadas están definidas por la implementación .
Controlador de señal para sistema operativo similar a Unix
Como el kernel llamará a un manejador de señales utilizando la convención de llamada C, debemos decirle al compilador que use la convención de llamada C al compilar la función.
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;
}
// ...
}
}
Hacer un encabezado de biblioteca C compatible con C ++
El encabezado de la biblioteca de CA generalmente se puede incluir en un programa de C ++, ya que la mayoría de las declaraciones son válidas tanto en C como en C ++. Por ejemplo, considere el siguiente foo.h
:
typedef struct Foo {
int bar;
} Foo;
Foo make_foo(int);
La definición de make_foo
se compila y distribuye por separado con el encabezado en forma de objeto.
Un programa de C ++ puede #include <foo.h>
, pero el compilador no sabrá que la función make_foo
está definida como un símbolo C, y probablemente intentará buscarlo con un nombre mutilado y no podrá localizarlo. Incluso si puede encontrar la definición de make_foo
en la biblioteca, no todas las plataformas usan las mismas convenciones de llamada para C y C ++, y el compilador de C ++ usará la convención de llamada de C ++ al llamar a make_foo
, lo que probablemente cause un error de segmentación si make_foo
está esperando ser llamado con la convención de llamadas C.
La forma de solucionar este problema es envolver casi todas las declaraciones en el encabezado en un bloque 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
Ahora, cuando se incluye foo.h
de un programa en C, simplemente aparecerá como declaraciones ordinarias, pero cuando se incluye foo.h
de un programa en C ++, make_foo
estará dentro de un bloque extern "C"
y el compilador sabrá si debe buscar un nombre no enredado y utilizar la convención de llamadas C.