我试图在Go中使用 GetRawInputDeviceList
函数,但不断出现以下错误:The parameter is incorrect.
对于official documentation:对于连接到系统的设备,第一个参数必须是 RAWINPUTDEVICELIST
结构的数组。我不太了解unsafe.Pointer
,指针算术(?)和我需要做的其他事情才能使其正常工作。
我发现this Medium article提供了一些指导,但它并不直接适用于我的用例。我没有足够的经验与指针和手动内存管理一起将其应用于我的问题。我不知道如何将this C++ example转换为Go,但我如此绝望,以至于我尝试将a working VBA solution转换为Go都没有成功。
关于此事,我有两个问题:
环境
这是我的系统/语言详细信息:
我的目标是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
}
最佳答案
首先,ERROR_INVALID_PARAMETER
错误是由最后一个参数引起的:cbSize
,根据文档,应始终将其设置为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 {
devices := make([]rawInputDeviceList, size * devCount) // <- 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[0], &devCount, size)
if err != nil {
fmt.Printf("Error: %v", err)
}
for i := 0; i < int(devCount); i++ {
fmt.Printf("Type: %v", devices[i].Type)
}
}
}
// 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
}
关于pointers - 如何在Go中使用Win32的GetRawInputDeviceList?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60662743/