Поделиться через


Спецификации компоновки

Термином "спецификация компоновки" обозначается протокол связывания функций (или процедур), написанных на разных языках. Затрагиваются следующие соглашения о вызовах:

  • Учет регистра в именах.

  • Декорирование имен. В языке C компилятор добавляет перед именами символ подчеркивания. Часто это называется "декорированием". В языке C++ декорирование имен используется для сохранения информации на этапе компоновки. (См. раздел Декорированные имена)

  • Порядок, в котором аргументы размещаются в стеке.

  • Ответственность за настройку стека при возврате из функции. Ответственность может лежать на вызываемой или вызывающей функции.

  • Передача скрытых аргументов (передаются ли какие-либо скрытые аргументы).

extern string-literal { declaration-list }
extern string-literal declaration

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

Блок, относящийся только к системам Microsoft

В настоящее время Microsoft C++ поддерживает только спецификации компоновки "C" и "C++".

Завершение блока, относящегося только к системам Microsoft

В следующем примере объявляются функции atoi и atol с компоновкой C:

extern "C"
{
    int  atoi( char *string );
    long atol( char *string );
}

Вызовы этих функций производятся с использованием компоновки C. Этот же результат можно получить с помощью следующих двух объявлений:

extern "C" int  atoi( char *string );
extern "C" long atol( char *string );

Блок, относящийся только к системам Microsoft

Все стандартные включаемые файлы Microsoft C содержат директивы условной компиляции для обнаружения компиляция C++. При обнаружении компиляции C++ прототипы заключаются в директиву extern "C", как показано ниже:

// Sample.h
#if defined(__cplusplus)
extern "C"
{
#endif

// Function declarations

#if defined(__cplusplus)
}
#endif 

Завершение блока, относящегося только к системам Microsoft

Нет необходимости объявлять функции в стандартных включаемых файлах как extern "C".

Если функция перегружена, описатель компоновки может иметь не более чем одна функция с таким именем. (Дополнительные сведения см. в разделе Перегрузка функций.)

В следующей таблице показано, как работают различные спецификации компоновки.

Действие спецификаций компоновки

Спецификация

Действие

Для объекта

Влияет на компоновку только этого объекта

Для функции

Влияет на компоновку этой функции и всех функций или объектов, объявленных в ней

Для класса

Влияет на компоновку всех объявленных в классе функций и объектов, не являющихся членами

Если у функции несколько спецификаций компоновки, они должны быть согласованы; если для функции объявлены компоновки C и C++ — это ошибка. Кроме того, если в программе имеются два объявления функции (одно со спецификацией компоновки, а другое без такой спецификации), объявление с указанием компоновки должен быть первым. Ко всем повторным объявлениям функций, уже имеющих спецификацию компоновки, применяется компоновка из первого объявления. Например:

extern "C" int CFunc1();
...
int CFunc1();            // Redeclaration is benign; C linkage is
                         //  retained.

int CFunc2();
...
extern "C" int CFunc2(); // Error: not the first declaration of
                         //  CFunc2;  cannot contain linkage
                         //  specifier.

Функции и объекты, явно объявленные как static в теле составного описателя компоновки ({ }), рассматриваются как статические функции или объекты; описатель компоновки игнорируется. Остальные функции и объекты ведут себя так, как если бы они были объявлены с помощью ключевого слова extern. (Подробнее о ключевом слове extern см. в разделе Использование extern для указания компоновки.)

См. также

Ссылки

Использование ключевого слова extern для задания компоновки