1

Тема: AHK: RegisterCallback() и количество параметров

В справке написано, что при создании колбека нужно убедиться, что количество параметров у вызова и принимающей функции должны совпадать.
А почему не написано.
Чем теоретически может обернуться если их количество совпадать не будет?
Например:

 EnumAddress := RegisterCallback("EnumWindowsProc", "Fast")
DllCall("EnumWindows", "Ptr", EnumAddress, "Ptr", 0)
MsgBox %Output%  ; Display the information accumulated by the callback.
    
EnumWindowsProc(hwnd, lParam, temp1, temp2, temp3)   ; 5 параметров вместо 2
{
    global Output
    WinGetTitle, title, ahk_id %hwnd%
    WinGetClass, class, ahk_id %hwnd%
    if title
        Output .= "HWND: " . hwnd . "`tTitle: " . title . "`tClass: " . class . "`n"
    return true  ; Tell EnumWindows() to continue until all windows have been enumerated.
}

2

Re: AHK: RegisterCallback() и количество параметров

В данном случае ничем, лишние просто не будут приходить. Наверно, имеется в виду, что если указано количество, то должно быть правильным, иначе просто интерпретатор выдаст ошибку.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: RegisterCallback() и количество параметров

teadrinker пишет:

иначе просто интерпретатор выдаст ошибку

Проверил, не выдаёт. Просто не сработает:

EnumAddress := RegisterCallback("EnumWindowsProc", "Fast", 3)
DllCall("EnumWindows", "Ptr", EnumAddress, "Ptr", 0)
MsgBox %Output%  ; Display the information accumulated by the callback.
    
EnumWindowsProc(hwnd, lParam)
{
    global Output
    WinGetTitle, title, ahk_id %hwnd%
    WinGetClass, class, ahk_id %hwnd%
    if title
        Output .= "HWND: " . hwnd . "`tTitle: " . title . "`tClass: " . class . "`n"
    return true  ; Tell EnumWindows() to continue until all windows have been enumerated.
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

4

Re: AHK: RegisterCallback() и количество параметров

Сейчас проверил код из первого поста на 32бит и если параметров больше, то выводит пустоту.

5

Re: AHK: RegisterCallback() и количество параметров

Да, в этом случае функция просто крашится:

counter := 0
EnumAddress := RegisterCallback("EnumWindowsProc", "Fast")
MsgBox, % DllCall("EnumWindows", "Ptr", EnumAddress, "Ptr", 0)
MsgBox %Output%  ; Display the information accumulated by the callback.
    
EnumWindowsProc(hwnd, lParam, a, b, c)   ; 5 параметров вместо 2
{
    global Output, counter
    ToolTip % ++counter
    WinGetClass, class, ahk_id %hwnd%
    WinGetTitle, title, ahk_id %hwnd%
    
    if title
        Output .= "HWND: " . hwnd . "`tTitle: " . title . "`tClass: " . class . "`n"
    return true  ; Tell EnumWindows() to continue until all windows have been enumerated.
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

6

Re: AHK: RegisterCallback() и количество параметров

Вызванная функция должна сама очищать стек от своих параметров (если соглашение вызова stdcall). Фактически в стеке 2 параметра, а функция уберёт 5, т.е. удалит лишнее.

7

Re: AHK: RegisterCallback() и количество параметров

А почему на 64 битах такой ситуации не наблюдается?
И если функция уберет 1 параметр вместо 2, то чем это чревато?

8

Re: AHK: RegisterCallback() и количество параметров

Malcev пишет:

И если функция уберет 1 параметр вместо 2, то чем это чревато?

Зависит от того, как код скомпилировался. Может, и ничего. Смотря от чего, например, адресуются локальные переменные, они ведь хранятся в стеке. Если от указателя стека, то он после вызова окажется не там, где был до вызова, и адресация собьётся.

Malcev пишет:

А почему на 64 битах такой ситуации не наблюдается?

Там соглашение вызова fastcall, где стек очищает вызывающая функция. Сколько положила, столько и уберёт.