Pointers 如何使用Win32';Go中的GetRawInputDeviceList是什么?

Pointers 如何使用Win32';Go中的GetRawInputDeviceList是什么?,pointers,go,winapi,Pointers,Go,Winapi,我正在尝试使用Go中的函数,但不断出现以下错误: 参数不正确。 根据:第一个参数需要是连接到系统的设备的结构数组。我不太明白不安全.指针、指针算术(?)和其他我需要做的事情的组合是什么,以使其正确工作 我发现这提供了一些指导,但它并不直接适用于我的用例。我没有足够的经验使用指针和手动内存管理来解决我的问题。我不知道如何翻译成围棋,我绝望地试图转换成围棋,但没有成功 关于这件事,我有两个问题: 如何将Go中的结构数组转换为Windows API调用所需的适当类型 如何将Windows API回调的

我正在尝试使用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
    
    代码 这是我正在努力工作的代码。我还没有对
    设备
    进行任何操作,但目标是使用句柄(
    rawInputDeviceList
    中的
    DeviceHandle
    )获取有关输入设备的信息

    主程序包
    进口(
    “fmt”
    “系统调用”
    “不安全”
    )
    //RAWINPUTDEVICELIST结构
    类型rawInputDeviceList结构{
    设备句柄uintptr
    uint32型
    }
    变量(
    user32=syscall.NewLazyDLL(“user32.dll”)
    getRawInputDeviceListProc=user32.NewProc(“GetRawInputDeviceList”)
    )
    func main(){
    dl:=rawInputDeviceList{}
    尺寸:=uint32(不安全尺寸(dl))
    //首先,我确定系统上有多少个输入设备
    //被分配给` devCount'`
    var devCount uint32
    _=getRawInputDeviceList(无和devCount,大小)
    如果devCount>0{
    大小=大小*devCount
    
    设备:=make([]rawInputDeviceList,size)/首先,
    错误\u无效\u参数
    错误是由最后一个参数引起的:
    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
    }
    
    主程序包
    进口(
    “fmt”
    “系统调用”
    “不安全”
    )
    //RAWINPUTDEVICELIST结构
    类型rawInputDeviceList结构{
    设备句柄uintptr
    uint32型
    }
    变量(
    user32=syscall.NewLazyDLL(“user32.dll”)
    getRawInputDeviceListProc=user32.NewProc(“GetRawInputDeviceList”)
    )
    func main(){
    dl:=rawInputDeviceList{}
    尺寸:=uint32(不安全尺寸(dl))
    //首先,我确定系统上有多少个输入设备
    //被分配给` devCount'`
    var devCount uint32
    _=getRawInputDeviceList(无和devCount,大小)
    如果devCount>0{
    
    devices:=make([]rawInputDeviceList,size*devCount)//您只需将其视为
    GetRawInputDeviceList
    指针,第二次传递的
    size
    已更改为
    size=size*devCount
    而不是
    sizeof(GetRawInputDeviceList)
    Hi,@Mike这对您的问题有帮助吗?Hi@drake wu msft,我为延迟回复道歉。我刚刚尝试了您的解决方案,效果很好。非常感谢您的帮助!