Поиск…


Вступление

Спецификация привязки сообщает компилятору компилировать объявления таким образом, чтобы их можно было связывать вместе с декларациями, написанными на другом языке, например C.

Синтаксис

  • extern string-literal { declaration-seq ( opt )}
  • ехЬегп строкового литерала декларация

замечания

Стандарт требует, чтобы все компиляторы поддерживали extern "C" , чтобы позволить C ++ быть совместимым с C и extern "C++" , который может использоваться для переопределения спецификации привязки и восстановления значения по умолчанию. Другие поддерживаемые спецификации привязки определены реализацией .

Обработчик сигналов для Unix-подобной операционной системы

Поскольку обработчик сигнала будет вызываться ядром с использованием соглашения о вызове C, мы должны сообщить компилятору использовать соглашение C-вызова при компиляции функции.

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

Создание заголовка библиотеки C, совместимого с C ++

Заголовок библиотеки AC обычно можно включить в программу на C ++, так как большинство объявлений действительны как для C, так и для C ++. Например, рассмотрим следующий foo.h :

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

Определение make_foo отдельно компилируется и распределяется с заголовком в виде объекта.

Программа C ++ может #include <foo.h> , но компилятор не будет знать, что функция make_foo определена как символ C и, вероятно, попытается найти ее с искаженным именем и не сможет ее найти. Даже если он может найти определение make_foo в библиотеке, не все платформы используют одни и те же соглашения о вызовах для C и C ++, а компилятор C ++ будет использовать соглашение о вызове C ++ при вызове make_foo , что может вызвать ошибку сегментации, если make_foo ожидается, что его вызывают с помощью соглашения о вызове C.

Способ устранения этой проблемы состоит в том, чтобы обернуть почти все объявления в заголовке во extern "C" блоке 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

Теперь, когда foo.h включен в программу C, он будет просто отображаться как обычные объявления, но когда foo.h будет включен из C ++-программы, make_foo будет находиться внутри extern "C" блока extern "C" и компилятор будет знать, что искать unmangled name и использовать соглашение вызова C.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow