Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CPlusPlusNotesForProfessionals.pdf
Скачиваний:
47
Добавлен:
20.05.2023
Размер:
5.11 Mб
Скачать

Chapter 134: Linkage specifications

A linkage specification tells the compiler to compile declarations in a way that allows them to be linked together with declarations written in another language, such as C.

Section 134.1: Signal handler for Unix-like operating system

Since a signal handler will be called by the kernel using the C calling convention, we must tell the compiler to use the C calling convention when compiling the function.

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;

}

// ...

}

}

Section 134.2: Making a C library header compatible with C++

A C library header can usually be included into a C++ program, since most declarations are valid in both C and C++. For example, consider the following foo.h:

typedef struct Foo { int bar;

} Foo;

Foo make_foo(int);

The definition of make_foo is separately compiled and distributed with the header in object form.

A C++ program can #include <foo.h>, but the compiler will not know that the make_foo function is defined as a C symbol, and will probably try to look for it with a mangled name, and fail to locate it. Even if it can find the definition of make_foo in the library, not all platforms use the same calling conventions for C and C++, and the C++ compiler will use the C++ calling convention when calling make_foo, which is likely to cause a segmentation fault if make_foo is expecting to be called with the C calling convention.

The way to remedy this problem is to wrap almost all the declarations in the header in an extern "C" block.

#ifdef __cplusplus extern "C" { #endif

typedef struct Foo { int bar;

} Foo;

Foo make_foo(int);

GoalKicker.com – C++ Notes for Professionals

640

#ifdef __cplusplus

} /* end of "extern C" block */

#endif

Now when foo.h is included from a C program, it will just appear as ordinary declarations, but when foo.h is included from a C++ program, make_foo will be inside an extern "C" block and the compiler will know to look for an unmangled name and use the C calling convention.

GoalKicker.com – C++ Notes for Professionals

641