Я пытаюсь использовать функцию GetRawInputDeviceList
в Go и получаю следующее сообщение об ошибке:
The parameter is incorrect.
В соответствии с официальная документация : первый параметр должен представлять собой массив структур RAWINPUTDEVICELIST
для устройств, подключенных к системе. Я не совсем понимаю, какую комбинацию unsafe.Pointer
, арифметику указателя c (?) И других вещей, которые мне нужно сделать, чтобы заставить это работать правильно.
Я нашел это Средняя статья , в которой содержатся некоторые рекомендации, но она не имеет прямого отношения к моему случаю использования. У меня недостаточно опыта работы с указателями и ручным управлением памятью, чтобы применить его к моей проблеме. Я не знаю, как перевести этот пример C ++ в Go, и я настолько отчаялся, что попытался преобразовать работающее VBA-решение в Go безуспешно.
У меня есть два вопроса по этому вопросу:
- Как преобразовать массив структур в Go в соответствующий тип, ожидаемый для Windows Вызов API?
- Как преобразовать результат обратного вызова API Windows в массив структур с заполненными данными?
Среда
Вот Сведения о моей системе / языке:
- macOS Mojave v10.14.6
- Go v1.10.7 (требуется для запуска исполняемых файлов на Windows XP)
Я нацеливаюсь на Windows XP, поэтому я запускаю следующую команду для его компиляции:
env GOOS=windows GOARCH=386 go1.10.7 build -o example.exe example.go
Код
Вот код, который я пытаюсь заставить работать. С devices
я пока ничего не делаю, но целью было бы использовать дескриптор (DeviceHandle
из rawInputDeviceList
) для получения информации об устройстве ввода.
package main
import (
"fmt"
"syscall"
"unsafe"
)
// RAWINPUTDEVICELIST structure
type rawInputDeviceList struct {
DeviceHandle uintptr
Type uint32
}
var (
user32 = syscall.NewLazyDLL("user32.dll")
getRawInputDeviceListProc = user32.NewProc("GetRawInputDeviceList")
)
func main() {
dl := rawInputDeviceList{}
size := uint32(unsafe.Sizeof(dl))
// First I determine how many input devices are on the system, which
// gets assigned to `devCount`
var devCount uint32
_ = getRawInputDeviceList(nil, &devCount, size)
if devCount > 0 {
size = size * devCount
devices := make([]rawInputDeviceList, size) // <- This is definitely wrong
for i := 0; i < int(devCount); i++ {
devices[i] = rawInputDeviceList{}
}
// Here is where I get the "The parameter is incorrect." error:
err := getRawInputDeviceList(&devices, &devCount, size)
if err != nil {
fmt.Printf("Error: %v", err)
}
}
}
// Enumerates the raw input devices attached to the system.
func getRawInputDeviceList(
rawInputDeviceList *[]rawInputDeviceList, // <- This is probably wrong
numDevices *uint32,
size uint32,
) error {
_, _, err := getRawInputDeviceListProc.Call(
uintptr(unsafe.Pointer(rawInputDeviceList)),
uintptr(unsafe.Pointer(numDevices)),
uintptr(size))
if err != syscall.Errno(0) {
return err
}
return nil
}