CGO 将 Xlib XEvent 结构转换为字节数组?

我正在 Golang 中创建一个简单的窗口管理器(基于 tinywm 中的 c 代码的代码)。要使用 Xlib,我使用的是 cgo,所以我的标题是:


// #cgo LDFLAGS: -lX11

// #include <X11/Xlib.h>

我有一个变量声明,例如:


event := C.XEvent{}

然后,我稍后在事件循环中使用它来分配给它:


C.XNextEvent(display, &event) // Yes, display is defined

但是,当我尝试访问事件的属性(例如 xbutton 或 xkey)时,出现错误:


event.xbutton undefined (type C.XEvent has no field or method xbutton)

当我查看 XEvent 的 cgo 输出时,它在_cgo_gotypes.go文件中如下所示:


type _Ctype_XEvent [192] byte

而且我无法弄清楚发生了什么,尽管我有一种预感,即[192] byteC 结构类型的类型非常错误。如果这有帮助,XEvent 结构在 C 库中看起来像这样:


typedef union _XEvent {


    int type;   /* must not be changed */

    XAnyEvent xany;

    XKeyEvent xkey;

    XButtonEvent xbutton;

    XMotionEvent xmotion;

    XCrossingEvent xcrossing;

    XFocusChangeEvent xfocus;

    XExposeEvent xexpose;

    XGraphicsExposeEvent xgraphicsexpose;

    XNoExposeEvent xnoexpose;

    XVisibilityEvent xvisibility;

    XCreateWindowEvent xcreatewindow;

    XDestroyWindowEvent xdestroywindow;

    XUnmapEvent xunmap;

    XMapEvent xmap;

    XMapRequestEvent xmaprequest;

    XReparentEvent xreparent;

    XConfigureEvent xconfigure;

    XGravityEvent xgravity;

    XResizeRequestEvent xresizerequest;

    XConfigureRequestEvent xconfigurerequest;

    XCirculateEvent xcirculate;

    XCirculateRequestEvent xcirculaterequest;

    XPropertyEvent xproperty;

    XSelectionClearEvent xselectionclear;

    XSelectionRequestEvent xselectionrequest;

    XSelectionEvent xselection;

    XColormapEvent xcolormap;

    XClientMessageEvent xclient;

    XMappingEvent xmapping;

    XErrorEvent xerror;

    XKeymapEvent xkeymap;

    long pad[24];

} XEvent;


莫回无
浏览 151回答 1
1回答

猛跑小猪

如cgo 文档中所述:由于 Go 在一般情况下不支持 C 的联合类型,因此 C 的联合类型表示为具有相同长度的 Go 字节数组。另一个 SO 问题:Golang CGo:将联合字段转换为 Go 类型或go-nuts 邮件列表帖子可能会提供进一步的帮助。简而言之,您将无法简单地使用或简单地与使用联合的 C 代码交互。至少,您需要设置类似 an 的东西unsafe.Pointer来手动操作字段/类型,并且您的示例看起来像是一个特别烦人的案例(即它不仅仅是上面链接案例中几种不同类型整数的联合)。鉴于名称,我的印象是您可能想要在 Go 中创建一个“事件”接口,并将每个必需的事件类型实现为实现该接口的 Go 类型。然后编写代码(在 Go 或 C 中),根据C.sizeof(int)Go“union”/[]byte的第一个字节转换为/从 C 联合(我认为第一个int type字段可能包含在每个中,如果 X… 事件类型) .
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go