go - 将 Go 与 cgo 和 Xlib 一起使用时出错

标签 go xlib cgo

我试图在 cgo 的帮助下将 C 代码重写为 Go,但是在尝试运行 go 代码时它给了我一些错误,我不知道如何解决。该代码允许在 Linux 桌面上获取鼠标点击的坐标。

C 代码:

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

int main () {
    int x=-1, y=-1;
    XEvent event;
    int button;
    Display *display = XOpenDisplay(NULL);
    if (display == NULL) {
    fprintf(stderr, "Cannot connect to X server!\n");
    exit (EXIT_FAILURE);
    }
    Window root= XDefaultRootWindow(display);
    XGrabPointer(display, root, False, ButtonPressMask, GrabModeAsync,
         GrabModeAsync, None, None, CurrentTime);
    while(1){
    XSelectInput(display, root, ButtonReleaseMask);
    while(1) {
      XNextEvent(display,&event);
      switch(event.type) {
    case ButtonPress:
        switch(event.xbutton.button) {
          case Button1:
          x=event.xbutton.x;
          y=event.xbutton.y;
          button=Button1;
          break;

          case Button3:
          x=event.xbutton.x;
          y=event.xbutton.y;
          button=Button3;
          break;
          default:
          break;

        }
        break;
    default:
        break;
      }
      if(x>=0 && y>=0)break;
    }

    if(button==Button1)printf("leftclick at %d %d \n",x,y);
    else printf("rightclick at %d %d \n",x,y);}
    XCloseDisplay(display);
    return 0;
}

去代码:

package main

// #cgo LDFLAGS: -lX11
// #include <X11/Xlib.h>
// #include <X11/Xutil.h>
import "C"

import (
    "fmt"
)

func main() {
    var x = -1
    var y = -1
    var event C.XEvent
    var button int
    var display = C.XOpenDisplay(nil)
    if display == nil {
        panic("Cannot connect to X server!\n")
    }

    var root = C.XDefaultRootWindow(display);
    C.XGrabPointer(display, root, C.False, C.ButtonPressMask, C.GrabModeAsync, 
        C.GrabModeAsync, C.None, C.None, C.CurrentTime)
    for {
        C.XSelectInput(display, root, C.ButtonReleaseMask)
        for {
            C.XNextEvent(display, &event)
            switch(C.event.type) {
                case C.ButtonPress:
                    switch C.event.xbutton.button  {
                        case C.Button1:
                            x=C.event.xbutton.x
                            y=C.event.xbutton.y
                            button=C.Button1
                            break

                        case Button3:
                            x=C.event.xbutton.x
                            y=C.event.xbutton.y
                            button=C.Button3
                            break
                            default:
                                break

                    }
                    break
                default:
                    break
            }
            if(x>=0 && y>=0) {
                break
            }
        }
        if(button==Button1) {
            fmt.Printf("leftclick at %d %d \n",x,y)
        }
        else  {
            fmt.Printf("rightclick at %d %d \n",x,y)
        }
    }
    C.XCloseDisplay(display)
}

Go 代码中的错误:

go run g.go
# command-line-arguments
./g.go:29:19: expected selector or type assertion, found 'type'
./g.go:58:3: expected statement, found 'else'
./g.go:63:3: expected '}', found 'EOF'

最佳答案

关于“type”的错误,是go中的保留字,不能直接访问。

根据 this posting您应该将引用更改为:

switch C.event._type {

此外,else 不能单独在一行中。 改成

if button == Button1 {
    fmt.Printf("leftclick at %d %d \n", x, y)
} else {
    fmt.Printf("rightclick at %d %d \n", x, y)
}

Switch 语句不会在 go 中失败,因此您的 break 语句是不必要的。

最后,确保在您的代码上运行 go fmt,您在不需要的地方使用了括号。

这是一个删除了中断的格式化版本,应该适合你(我没有测试这段代码):

package main

// #cgo LDFLAGS: -lX11
// #include <X11/Xlib.h>
// #include <X11/Xutil.h>
import "C"

import (
    "fmt"
)

func main() {
    var x = -1
    var y = -1
    var event C.XEvent
    var button int
    var display = C.XOpenDisplay(nil)
    if display == nil {
        panic("Cannot connect to X server!\n")
    }

    var root = C.XDefaultRootWindow(display)
    C.XGrabPointer(display, root, C.False, C.ButtonPressMask, C.GrabModeAsync,
        C.GrabModeAsync, C.None, C.None, C.CurrentTime)
    for {
        C.XSelectInput(display, root, C.ButtonReleaseMask)
        for {
            C.XNextEvent(display, &event)
            switch C.event._type {
            case C.ButtonPress:
                switch C.event.xbutton.button {
                case C.Button1:
                    x = C.event.xbutton.x
                    y = C.event.xbutton.y
                    button = C.Button1

                case Button3:
                    x = C.event.xbutton.x
                    y = C.event.xbutton.y
                    button = C.Button3
                }
            }
            if x >= 0 && y >= 0 {
                break
            }
        }
        if button == Button1 {
            fmt.Printf("leftclick at %d %d \n", x, y)
        } else {
            fmt.Printf("rightclick at %d %d \n", x, y)
        }
    }
    C.XCloseDisplay(display)
}

关于go - 将 Go 与 cgo 和 Xlib 一起使用时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34243761/

相关文章:

json - Golang 修改没有结构的 json

go - go.mod 中的模块名称别名

postgresql - Golang GORM 搜索条件

go - 从 C 构建示例时出现错误 : Could not determine kind of name for C. stdout?去?加油!文章

go - 将 []float32 转换为 C *float

c - 将字符串文字传递给 C

go - 初始化嵌套的匿名结构

python xlib xgrabkey keyrelease 事件未触发

c - Xlib 多显示器支持

XLib 的 Java 绑定(bind)