【发布时间】:2020-03-12 22:42:49
【问题描述】:
我正在尝试在 Go 中使用 GetRawInputDeviceList 函数,但我不断收到以下错误:
The parameter is incorrect.
根据official documentation:第一个参数必须是连接到系统的设备的RAWINPUTDEVICELIST 结构数组。我不太明白unsafe.Pointer、指针算术(?)和其他我需要做的组合才能使其正常工作。
我发现this Medium article 提供了一些指导,但它并不直接适用于我的用例。我没有足够的使用指针和手动内存管理的经验来将其应用于我的问题。我不知道如何将 this C++ example 转换为 Go,我非常绝望,以至于我试图将 a working VBA solution 转换为 Go,但没有成功。
我有两个关于此事的问题:
- 如何将 Go 中的结构数组转换为 Windows API 调用所需的适当类型?
- 如何将 Windows API 调用的结果转换回具有填充数据的结构数组?
环境
这是我的系统/语言详细信息:
- 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 做任何事情,但目标是使用句柄(来自rawInputDeviceList 的DeviceHandle)来获取有关输入设备的信息。
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
}
【问题讨论】:
-
你只要把它当成一个
GetRawInputDeviceList指针,第二次传递的size已经改成size = size * devcount而不是sizeof (GetRawInputDeviceList)