Recherche…


Introduction

Une spécification de liaison indique au compilateur de compiler les déclarations de manière à ce qu’elles puissent être associées à des déclarations écrites dans un autre langage, tel que C.

Syntaxe

  • extern string-literal { declaration-seq ( opt )}
  • déclaration de chaîne de caractères externe

Remarques

La norme exige que tous les compilateurs prennent en charge extern "C" pour permettre à C ++ d'être compatible avec C, et extern "C++" , qui peut être utilisé pour remplacer une spécification de liaison englobante et restaurer la valeur par défaut. Les autres spécifications de liaison prises en charge sont définies par la mise en œuvre .

Gestionnaire de signal pour un système d'exploitation de type Unix

Étant donné qu'un gestionnaire de signaux sera appelé par le noyau à l'aide de la convention d'appel C, nous devons indiquer au compilateur d'utiliser la convention d'appel C lors de la compilation de la fonction.

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

Rendre un en-tête de bibliothèque C compatible avec C ++

L'en-tête de bibliothèque AC peut généralement être inclus dans un programme C ++, puisque la plupart des déclarations sont valides en C et en C ++. Par exemple, considérez le foo.h suivant:

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

La définition de make_foo est compilée et distribuée séparément avec l'en-tête sous forme d'objet.

Un programme C ++ peut #include <foo.h> , mais le compilateur ne saura pas que la fonction make_foo est définie comme un symbole C et essaiera probablement de la rechercher avec un nom déformé et ne pourra pas la localiser. Même si elle peut trouver la définition de make_foo dans la bibliothèque, toutes les plates - formes utilisent les mêmes conventions d'appel pour C et C ++, et le compilateur C ++ utilisera la convention d' appel C ++ lors de l' appel make_foo , ce qui est susceptible de provoquer une erreur de segmentation si make_foo s'attend à être appelé avec la convention d'appel C.

La manière de remédier à ce problème consiste à envelopper presque toutes les déclarations de l’en-tête dans un bloc 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

Maintenant, quand foo.h est inclus dans un programme C, il apparaîtra simplement comme des déclarations ordinaires, mais quand foo.h est inclus dans un programme C ++, make_foo sera dans un bloc extern "C" et le compilateur saura le rechercher. un nom non modifié et utilisez la convention d'appel C.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow