Бьерн Страуструп. Язык программирования С++ Второе дополненное издание


 Связывание с программами на других языках



Pdf көрінісі
бет86/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   82   83   84   85   86   87   88   89   ...   256
4.4 Связывание с программами на других языках 
Программы на С++ часто содержат части, написанные на других языках, и наоборот, часто фрагмент на 
С++ используется в программах, написанных на других языках. Собрать в одну программу фрагменты, 
написанные на разных языках, или, написанные на одном языке, но в системах программирования с 
разными соглашениями о связывании, достаточно трудно. Например, разные языки или разные 
реализации одного языка могут различаться использованием регистров при передаче параметров, 
порядком размещения параметров в стеке, упаковкой таких встроенных типов, как целые или строки, 
форматом имен функций, которые транслятор передает редактору связей, объемом контроля типов, 
который требуется от редактора связей. Чтобы упростить задачу, можно в описании внешних указать 
условие связывания. Например, следующее описание объявляет strcpy внешней функцией и указывает, 
что она должна связываться согласно порядку связывания в С: 
extern "C" char* strcpy(char*, const char*); 
Результат этого описания отличается от результата обычного описания 
extern char* strcpy(char*, const char*); 
только порядком связывания для вызывающих strcpy() функций. Сама семантика вызова и, в частности
контроль фактических параметров будут одинаковы в обоих случаях. Описание extern "C" имеет смысл 
использовать еще и потому, что языки С и С++, как и их реализации, близки друг другу. Отметим, что в 
описании extern "C" упоминание С относится к порядку связывания, а не к языку, и часто такое описание 
используют для связи с Фортраном или ассемблером. Эти языки в определенной степени подчиняются 
порядку связывания для С. 
Утомительно добавлять "C" ко многим описаниям внешних, и есть возможность указать такую 
спецификацию сразу для группы описаний. Например: 
extern "C" { 
char* strcpy(char*, const char); 
int strcmp(const char*, const char*) 
int strlen(const char*) 


Бьерн Страуструп.
Язык программирования С++ 
 
105 
// 
... 

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

Обычно с помощью такого приема из стандартного заголовочного файла для С получают такой файл 
для С++. Возможно иное решение с помощью условной трансляции: 
#ifdef __cplusplus 
extern "C" { 
#endif 
char* strcpy(char*, const char*); 
int strcmp(const char*, const char*); 
int strlen(const char*); 
// ... 
#ifdef __cplusplus 

#endif 
Предопределенное макроопределение __cplusplus нужно, чтобы обойти конструкцию extern "C" { ...}, 
если заголовочный файл используется для С. 
Поскольку конструкция extern "C" { ... } влияет только на порядок связывания, в ней может содержаться 
любое описание, например: 
extern "C" { 
// произвольные описания 
// 
например: 
static int st; 
int 
glob; 

Никак не меняется класс памяти и область видимости описываемых объектов, поэтому по-прежнему st 
подчиняется внутреннему связыванию, а glob остается глобальной переменной. 
Укажем еще раз, что описание extern "C" влияет только на порядок связывания и не влияет на порядок 
вызова функции. В частности, функция, описанная как extern "C", все равно подчиняется правилам 
контроля типов и преобразования фактических параметров, которые в C++ строже, чем в С. Например: 
extern "C" int f(); 
int g() 

return f(1); // ошибка: параметров быть не должно 



Достарыңызбен бөлісу:
1   ...   82   83   84   85   86   87   88   89   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет