Указатель функции и соглашение о вызовах

float __stdcall (*pFunc)(float a, float b) = (float (__stdcall *)(float,float))0x411280;

Как объявить указатель функции с соглашением о вызовах? Вышеупомянутое дает мне ошибку.


person Yulo    schedule 28.01.2011    source источник
comment
@James Возможно, соглашение о вызовах не может сопровождаться вложенным декларатором.   -  person smwikipedia    schedule 19.10.2018


Ответы (3)


Хитрость заключается в том, чтобы поместить __stdcall в круглые скобки следующим образом:

float (__stdcall *pFunc)(float a, float b) = (float (__stdcall *)(float,float))0x411280;

Конечно, вместо этого рекомендуется использовать typedef, но применяется тот же трюк:

typedef float (__stdcall *FuncType)(float a, float b);
person namey    schedule 28.01.2011
comment
Поправьте меня, если я ошибаюсь, но разве мы не хотим typedef float (__stdcall *FuncType)(float a, float b)? - person zeboidlund; 15.10.2013

Для обычной функции вы обычно можете сделать:

__cdecl const int func();
__cdecl const int (func)();
const __cdecl int func();
const int __cdecl func();
const int (__cdecl func)();
__cdecl const __cdecl int (__cdecl func)();

Реализация определяет, будет ли компилятор принимать все эти формы. Клэнг делает. Для меня 5-я версия имеет наиболее семантический смысл, потому что это свойство функции, а не только тип возвращаемого значения.

Вы можете сделать все это с помощью __attribute__((cdecl)) вместо __cdecl, который также можно использовать после функции, в отличие от __cdecl

const int (__cdecl func)() __attribute__((cdecl));

Теперь, чтобы объявить постоянный указатель pfunc на функцию с определенным соглашением о вызовах:

__cdecl const int (*const pfunc)();
const __cdecl int (*const pfunc)();
const int __cdecl (*const pfunc)();
const int (__cdecl *const pfunc)();
const int (*const __cdecl pfunc)();
const int (*__cdecl const pfunc)();
__cdecl const __cdecl int (__cdecl *const pfunc)();
const int (*const pfunc)() __attribute__((cdecl));

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

Опять же, это реализация, определяемая тем, какую форму принимает компилятор. Clang принимает все формы и корректно интерпретирует их как тип const int (*const)() __attribute__((cdecl))

person Lewis Kelsey    schedule 29.05.2020

__fastcall является оптимизированным (самое быстрое соглашение о вызовах), но не используется по неизвестной причине.

Пытаться:

int (__fastcall *myfunction)(int,float);
person Mandrake    schedule 28.01.2011
comment
Вы должны были взглянуть на эти неизвестные причины, прежде чем публиковать, и в конечном итоге задать новый вопрос, если он еще не задан. Этот сайт предназначен для обмена знаниями, а не предположениями. - person Johan Boulé; 08.07.2018