Что делает объявление CALLBACK в C? - PullRequest
9 голосов
/ 10 февраля 2009

Я просматривал код из библиотеки SDL и наткнулся на функцию, объявленную так:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

Теперь я кодер Delphi. Нет hablo C muy bien, сеньор. Но я помню достаточно синтаксиса из моих курсов в колледже, чтобы прочитать его так:

Имя функции - WndProc. Список аргументов довольно понятен. Тип возврата функции - LRESULT. Но что в мире делает этот «ЗВОНОК»? В Delphi любая функция может использоваться как обратный вызов; вам просто нужно передать правильный тип указателя на функцию. Есть ли какая-то конкретная причина, почему C не работает таким образом? Или это означает что-то другое?

Ответы [ 4 ]

14 голосов
/ 10 февраля 2009

«ЗВОНОК» - это соглашение о вызовах. Существуют и другие виды соглашений о вызовах. CALLBACK такой же, как __stdcall.

http://www.codeguru.com/cpp/cpp/cpp_mfc/callbacks/article.php/c10557

Еще немного информации в блоге Раймонда Чена:

http://blogs.msdn.com/oldnewthing/archive/2004/01/08/48616.aspx

4 голосов
/ 10 февраля 2009

Короткий обзор из блога Раймонда Чена:

Отличная вещь о звонках соглашения на платформе x86 что есть из чего выбирать!

Соглашение о вызовах C (__cdecl)

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

Соглашение о вызовах Паскаля (__pascal )

Pascal не поддерживает функции с переменным числом параметров, поэтому он может использовать соглашение о чистоте вызываемого абонента. Параметры вводятся слева направо. Почти все функции Win16 экспортируются как соглашение о вызовах Pascal. Соглашение о чистом вызове экономит три байта в каждой точке вызова с фиксированными издержками в два байта на функцию. Это было также немного быстрее. На Win16 экономия нескольких сотен байтов и нескольких циклов была большой проблемой. Примечание. Соглашение о вызовах Фортрана (__fortran) такое же, как соглашение о вызовах Паскаля

2 голосов
/ 10 февраля 2009

Это соглашение о вызовах. Это требуется, когда вы передаете указатель на эту функцию в Windows API, который позже вызывает эту функцию. Соглашение о вызовах Windows отличается от соглашения о вызовах C, поэтому необходимо указать компилятору, что WndProc () является специальным и что ему требуется другой код запуска и очистки.

0 голосов
/ 10 февраля 2009

Это соглашение о вызовах, и в Delphi они тоже есть. Попробуйте найти «cdecl» в справке Delphi. В Delphi (или Object Pascal, как нам нравится называть его в давние времена) соглашения о вызовах идут после объявления функции, например:

function MyFunction(X, Y: Real): Real; cdecl;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...