Зачем нужно использовать WINAPI * для синтаксиса для объявления указателей функций для функций в DLL

У меня есть консольное приложение C++ и DLL. В приложении C++ я вижу следующий фрагмент::

typedef DWORD (WINAPI* functABC)(unsigned long*);

functABC functABC111;
HMODULE handleDLL = LOadLibrary("a.DLL");
functABC111 = (functABC)GetProcAddress(handleDLL,"function_1");

На высоком уровне я понимаю, что мы получаем указатель функции на функцию в .DLL "function_1()".

Но хочу понять первые 2 строки в приведенном выше фрагменте ::

typedef DWORD (WINAPI* functABC)(unsigned long*);
functABC functABC111;

2 вопроса :: 1) Является ли имя "functABC" просто случайным именем указателя на функцию?
2) Что мы технически делаем в этих двух строках. Объявление указателя на функцию.
3) Зачем нам нужно использовать WINAPI* в объявлении указателя на функцию в 1-й строке.

Заранее спасибо.


person codeLover    schedule 20.09.2013    source источник


Ответы (3)


  1. 'functABC' – это определение типа для функции, возвращающей DWORD и принимающей в качестве параметра длинный указатель без знака.

  2. Первые строки определяют typedef, а вторая создает с его помощью указатель на функцию.

  3. 'WINAPI' – это макрос, который обычно расширяется до '__stdcall – соглашения о вызовах, используемого корпорацией Майкрософт для экспорта функций из .DLL

person user1233963    schedule 20.09.2013
comment
2 вопроса :: functABC - это просто имя typedef, поэтому, очевидно, мы можем указать любое имя. И можно ли использовать переменную указателя функции, созданную из этого typedef (в нашем случае functABC111), для указания на любую функцию с этой сигнатурой?? Если есть несколько функций с одинаковой сигнатурой, нам нужно создать различные переменные-указатели функций, такие как functABC111_1, functABC111_2 и т. д., все типа functABC. Я прав ? - person codeLover; 20.09.2013
comment
Ваш третий пункт несколько вводит в заблуждение. Нет необходимости использовать __stdcall при экспорте функции из .dll. Вы также можете экспортировать функцию, используя __cdecl. Однако важно, чтобы объявление и реализация функции имели совпадающие соглашения о вызовах. Для x64 все проще: существует только одно соглашение о вызовах. - person IInspectable; 20.09.2013

3) Почти все функции Windows (от shell32.dll, user32.dll и всех прочих) объявлены как __stdcall, или как WINAPI (одно и то же). Нет необходимости объявлять функции в DLL как WINAPI, но люди просто следуют примеру Microsoft. Код будет на несколько байт меньше, а выполнение на несколько наносекунд короче.

person Dialecticus    schedule 20.09.2013

2) Что мы технически делаем в этих 2 строчках. Объявление указателя на функцию.

Сначала определяется тип, который можно использовать для указания на любую функцию, следующую за прототипом DWORD WINAPI funcName(unsigned long*);. Затем создается переменная этого типа.

3) Зачем нам нужно использовать WINAPI* в объявлении указателя функции в 1-й строке.

Поскольку function_1 использует соглашение о вызовах WINAPI (обычно определяется как __stdcall). Или, по крайней мере, этот код предполагает, что это так.

person Michael    schedule 20.09.2013