C++ Academy · Урок

Extern C и ABI языка C

Предоставляйте совместимые с C интерфейсы из библиотек C++ с помощью extern C.

Урок 1 из 414 шагов

«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 — локальная установка не требуется.

Все уроки этого курса

  1. Extern C и ABI языка C
  2. Вызов Python из C++ через pybind11
  3. C++ для границ FFI Rust
  4. Использование SWIG для привязок нескольких языков
← Назад к C++ Academy