Extern C и ABI языка C
Предоставляйте совместимые с C интерфейсы из библиотек C++ с помощью extern C.
«Extern C и ABI языка C» — бесплатный урок C++ Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.
Зачем нужна совместимость
У C++ сложный ABI (двоичный интерфейс приложения), включающий искажение имён, исключения и шаблоны. Другие языки (C, Python, Rust) не могут напрямую использовать символы C++ с искажёнными именами.
extern "C"
Заключайте объявления в extern "C", чтобы отключить искажение имён C++ и использовать соглашение о вызовах C.
extern "C" {
void greet(const char* name);
int add(int a, int b);
}Почему именно C ABI
C ABI — общий знаменатель для разных языков. Практически любой язык может вызывать функции C через FFI.
Шаблон файла заголовка
Сделайте заголовок совместимым с C и C++ с помощью условного extern "C".
#ifdef __cplusplus
extern "C" {
#endif
void hello(void);
int sum(int a, int b);
#ifdef __cplusplus
}
#endifЧто нельзя экспортировать
Некоторые возможности C++ не имеют эквивалента в C:
- Классы (в C нет понятия класса)
- Шаблоны (разрешаются во время компиляции и не экспортируются)
- Перегруженные функции (без искажения имён перегрузка невозможна)
- Исключения (их необходимо перехватить до пересечения границы FFI)
Предоставление класса
Скройте класс за непрозрачными указателями и API в стиле C.
// header (C visible)
typedef struct Widget Widget;
Widget* widget_create(int x);
void widget_destroy(Widget*);
int widget_value(const Widget*);
// .cpp
class WidgetImpl { /* ... */ };
extern "C" {
Widget* widget_create(int x) { return reinterpret_cast<Widget*>(new WidgetImpl(x)); }
void widget_destroy(Widget* w) { delete reinterpret_cast<WidgetImpl*>(w); }
}Избегайте исключений через FFI
Исключение, выброшенное функцией C++, вызванной через C, приведёт к аварийному завершению. Перехватывайте исключения на границе.
extern "C" int safe_call() {
try {
risky();
return 0;
} catch (...) {
return -1;
}
}Владение памятью
Документируйте, кто чем владеет: обычно освобождает память та сторона, которая её выделила. Несоответствия приводят к утечкам или двойному освобождению.
Строки через FFI
std::string доступна только в C++. Передавайте строки через FFI как const char*. Определите, создаёт ли получатель копию, и документируйте время жизни данных.
Структуры через FFI
Используйте структуры POD (простых данных), имеющие одинаковое расположение полей в C и C++. Избегайте виртуальных функций, ссылок и типов std.
Обратные вызовы
Передавайте через FFI указатели на функции (или void* вместе с указателем на функцию). Предоставляйте указатель на контекст для замыканий.
extern "C" {
typedef void (*Callback)(int value, void* user_data);
void register_callback(Callback cb, void* user_data);
}Связывание и заголовки
extern "C" влияет только на связывание, но не на поведение. Функция по-прежнему компилируется внутри как C++, но снаружи доступна для вызова как функция C.
Быстрая проверка
Зачем заключать функции C++ в extern "C" при предоставлении доступа к ним из других языков?
Итоги
extern "C" задаёт для функции связывание C: без искажения имён и с соглашением о вызовах C. Используйте его, чтобы предоставлять доступ к C++ из других языков через FFI. Скрывайте классы за непрозрачными указателями, перехватывайте исключения на границе и чётко документируйте владение памятью.
Изучай C++ с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 51
- Уроки
- 203
Часто задаваемые вопросы
Урок «Extern C и ABI языка C» бесплатный?
Да — полный текст урока «Extern C и ABI языка C» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.
Чему я научусь в уроке «Extern C и ABI языка C»?
Предоставляйте совместимые с C интерфейсы из библиотек C++ с помощью extern C. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C++ Academy?
Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Extern C и ABI языка C»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C++ Academy?
Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Extern C и ABI языка C
- Вызов Python из C++ через pybind11
- C++ для границ FFI Rust
- Использование SWIG для привязок нескольких языков