С++ Тип функции?
Я новичок в учебе и изучаю С++ (знаю много Java), и следующий код меня смущает...
![enter image description here]()
Я знаю, что этот фрагмент кода имеет дело с указателем на функцию (это обратный вызов, что имеет смысл), но то, что меня отбрасывает, является аргументом между типом возвращаемого значения и именем функции. Что это за чертовщина?
Он похож на тип функции, но я никогда не слышал об этом, и даже после поиска и чтения о указателе на функции я не смог найти ничего, говоря о том, что функции могут иметь тип.
Если это так, как определить тип функции?
Спасибо, -Cody
Ответы
Ответ 1
GLFWCALL
не является типом, это макрос, который расширяется до соглашения о вызове, определенного для платформы, или пустую строку. Здесь обрезанный фрагмент glfw.h:
#if defined(_WIN32) && defined(GLFW_BUILD_DLL)
#define GLFWCALL __stdcall
#elif defined(_WIN32) && defined(GLFW_DLL)
#define GLFWCALL __stdcall
#else
/* We are either building/calling a static lib or we are non-win32 */
#define GLFWCALL
#endif
Использование правильного соглашения о вызове важно для x86/win32, так как некоторые из них ожидают, что стек будет очищен вызываемым абонентом и другими пользователями. Также могут быть различия в порядке прохождения аргументов.
Ответ 2
В Windows GLFWCALL
- макрос для __stdcall
, а на других платформах это макрос для ничего.
__stdcall
реализует конкретное соглашение о вызове и является расширением компилятора поверх обычных C или С++.
Макросы - это фрагменты кода, которые заменяют ваш код до того, как лексер и парсер вашего компилятора взаимодействуют с ними.
Ответ 3
GLFWCALL
- это макрос, который может расширяться до соглашения о вызовах, если это необходимо. Поскольку эта функция будет вызываться внешним кодом, она должна использовать соглашение о вызове, которое ожидает внешний код. Например, если функция помещает свое возвращаемое значение в стек, а внешний код ожидает его в регистре, стрела.
Ответ 4
Вопрос, обозначенный частью сигнатуры функции, представляет собой макрос препроцессора, который определен где-то еще в заголовке. Некоторые функции на некоторых платформах имеют дополнительные требования.
Например, функции в DLL файлах на платформе Windows часто используют модификатор __declspec (dllexport), но когда один и тот же заголовок включен в пользовательский проект, им необходимо использовать __declspec (dllimport). Использование макроса препроцессора для этой цели означает, что они могут просто использовать этот макрос для всех соответствующих функций и просто определять макрос по-разному при компиляции их собственной DLL или пользовательской DLL и на платформах, где __declspec не имеет значения, он может быть определен ни к чему. Есть много других причин для таких макросов, как этот.
В этом конкретном случае вы можете эффективно притворяться, что макрос пуст и полностью игнорирует его.