С++ для начинающих




Указатели на функции, объявленные как extern "C"


Можно объявлять указатели на функции, написанные на других языках программирования. Это делается с помощью директивы связывания. Например, указатель pf ссылается на С-функцию:

extern "C" void (*pf)(int);

Через pf вызывается функция, написанная на языке С.

extern "C" void exit(int);

// pf ссылается на C-функцию exit()

extern "C" void (*pf)(int) = exit;

int main() {

    // ...

    // вызов С-функции, а именно exit()

    (*pf)(99);

}

Вспомним, что присваивание и инициализация указателя на функцию возможны лишь тогда, когда тип в левой части оператора присваивания в точности соответствует типу в правой его части. Следовательно, указатель на С-функцию не может адресовать функцию С++ (и инициализация его таким адресом не допускается), и наоборот. Подобная попытка вызывает ошибку компиляции:

void (*pfl)(int);

extern "C" void (*pf2)(int);

int main() {

    pfl = pf2; // ошибка: pfl и pf2 имеют разные типы

    // ...

}

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

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

В следующем примере параметр pfParm также служит указателем на С-функцию. Директива связывания применяется к объявлению функции, к которой этот параметр относится:

// pfParm - указатель на С-функцию

extern "C" void f1( void(*pfParm)(int) );

Следовательно, f1() является С-функцией с одним параметром – указателем на С-функцию. Значит, передаваемый ей аргумент должен быть либо такой же функцией, либо указателем на нее, поскольку считается, что указатели на функции, написанные на разных языках, имеют разные типы. (Снова заметим, что в тех реализациях С++, где указатели на функции С и С++ имеют одинаковые характеристики, компилятор может поддерживать расширение языка, позволяющее не различать эти два типа указателей.)




Содержание  Назад  Вперед