|
#1
|
||||
|
||||
Callback функции
Приветствую!
Столкнулся с тем, что понадобилось использовать callback functions. В исходниках (заголовочные файлы) функции определены как: Код:
WINBASEAPI BOOL WINAPI EnumFuncA( _In_ A_ENUMPROC lpEnumProc, _In_ DWORD dwFlags, _In_ LONG_PTR lParam); WINBASEAPI BOOL WINAPI EnumFuncB( _In_ B_ENUMPROC lpEnumProc, _In_ DWORD dwFlags); Код:
#ifdef STRICT typedef BOOL (CALLBACK* A_ENUMPROC)(LPSTR, LPSTR, LPSTR, DWORD, LONG_PTR); typedef BOOL (CALLBACK* B_ENUMPROC)(LPSTR); #else typedef FARPROC A_ENUMPROC; typedef FARPROC B_ENUMPROC; #endif Гугл мне тут не помог. Благодарю заранее за помощь. UPD (нашел и сами функции): Код:
BOOL CALLBACK EnumProc_A( _In_ LPSTR lpArg0, _In_ LPSTR lpArg1, _In_ LPSTR lpArg2, _In_ DWORD dwFlags, _In_ LONG_PTR lParam ); BOOL CALLBACK EnumProc_B( _In_ LPSTR lpArg ); Последний раз редактировалось Sergios, 07.10.2014 в 22:15. |
#2
|
||||
|
||||
Адрес Callback'а передается в функцию перечисления, и оттуда вызывается. Точное совпадение типов не обязательно (можно и DWORD'ами все заменить), но тогда будет неудобно использовать. Перевод:
BOOl - boolean; CALLBACK - насколько помню, задефайнен на модификатор stdcall; _In_ - не важен в данном случае; LPSTR - PChar; DWORD - DWORD; LONG_PTR - по-моему, он Int64. Но лучше посмотреть в хедерах/MSDN. Так что Код:
BOOL CALLBACK EnumProc_B( _In_ LPSTR lpArg); Код:
function EnumProc_B(lpArg: PChar): boolean; stdcall; jmp $ ; Happy End! The Cake Is A Lie. |
#3
|
||||
|
||||
Как ни странно, но тип BOOL в WinAPI определен как знаковое целое (int) . Поэтому не совсем корректно приравнивать его к Boolean (этот тип вообще предпочитаю не использовать). Некоторые АПИшные функции могут возвращать true как отрицательное число...
LONG_PTR для win32 определен как long, а для win64 как __int64, что соответствует типам LongInt и Int64, соответственно. Методом научного тыка разобрался с вопросом. Покажу на примере второй функции. 1. Определяем тип-функцию. Код:
type B_ENUMPROC= function (lpArg: PChar): BOOL; stdcall; 2. Описываем импортируемую функцию. Код:
EnumFuncB(lpEnumProc: B_ENUMPROC; dwFlags: Dword): BOOL; stdcall; external 'Oops.dll' name 'EnumFuncB'; 3. Определяем прототип callback-функции в строгом соответствии с п.1. Код:
function EnumProcCallback(Arg: PChar): BOOL; stdcall; 4. определяем реализацию функции: Код:
begin if Arg<>nil then begin ; // что-то делаем с полученным аргументом end Result:=1; // True, если хотим продолжения перечисления, False (Result:=0), если не желаем продолжения end; 5. Вызов функции перечисления. Код:
EnumFuncB(@EnumProcCallback, (Flag1 or Flag2 or Flag3)); // пример комбинации из трех флагов, определенных в секции const. In omnia paratus Последний раз редактировалось Sergios, 12.10.2014 в 15:37. |
#4
|
|||
|
|||
Цитата:
При его отсутствии будет делаться дополнительная проверка типа передаваемой функции. и ещё Лучше вместо PChar явно писать PAnsiChar. Для старых версий Delphi не повредит, а в новых не будут появляться возможные ошибки |
#5
|
||||
|
||||
Цитата:
Код:
typedef BOOL (CALLBACK* B_ENUMPROC)(LPSTR); Цитата:
In omnia paratus |