Closed
Description
What version of Go are you using (go version
)?
1.20.3.
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (go env
)?
Windows 10,
Intel x86-64.
What did you do?
I create a callback and try to get it working.
I create a hook method to listen to system's events from a keyboard.
I send some keyboard events, but the callback is not started.
When the callback should be "fired", it does not "fire".
Code example is following.
package main
import "C"
import (
"fmt"
"log"
"time"
"golang.org/x/sys/windows"
)
var (
kernel32DLL = windows.NewLazySystemDLL("kernel32.dll")
user32DLL = windows.NewLazySystemDLL("user32.dll")
procGetCurrentThreadId = kernel32DLL.NewProc("GetCurrentThreadId")
procSetWindowsHookExW = user32DLL.NewProc("SetWindowsHookExW")
procCallNextHookEx = user32DLL.NewProc("CallNextHookEx")
)
var hook uintptr
const (
// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexw
WH_KEYBOARD = 2
WH_KEYBOARD_LL = 13
)
func mustBeNoError(err error) {
if err != nil {
panic(err)
}
}
func main() {
var err = kernel32DLL.Load()
mustBeNoError(err)
defer func() {
derr := windows.FreeLibrary(windows.Handle(kernel32DLL.Handle()))
if derr != nil {
log.Println(derr)
}
}()
err = user32DLL.Load()
mustBeNoError(err)
defer func() {
derr := windows.FreeLibrary(windows.Handle(user32DLL.Handle()))
if derr != nil {
log.Println(derr)
}
}()
threadId, _, _ := procGetCurrentThreadId.Call()
fmt.Println("ThreadId:", threadId)
//callback := syscall.NewCallback(callbackFunc)
callback := windows.NewCallback(callbackFunc)
defer func() {
// Callback release is not available in Golang.
// What should I do when the limit is reached ? ...
}()
hook, _, _ = procSetWindowsHookExW.Call(WH_KEYBOARD, callback, 0, threadId)
fmt.Println("hook:", hook)
time.Sleep(time.Second * 10)
}
func callbackFunc(code, wParam, lParam uintptr) uintptr {
ret, _, _ := procCallNextHookEx.Call(hook, code, wParam, lParam)
fmt.Println("inside callbackFunc")
return ret
}
I tried:
callback := syscall.NewCallback(callbackFunc)
callback := windows.NewCallback(callbackFunc)
- with
import "C"
- without
import "C"
WH_KEYBOARD
WH_KEYBOARD_LL
but the result stays the same. It does not work.
What did you expect to see?
I expect to see working callbacks on Windows O.S. in Golang.
What did you see instead?
I see broken callbacks on Windows O.S. in Golang.
Program's output was:
ThreadId: 12984
hook: 30737909