CGO 将 Xlib XEvent 结构转换为字节数组?
CGO converting Xlib XEvent struct to byte array?
我正在 Golang 中创建一个简单的 window 管理器(代码基于 tinywm 中的 c 代码)。为了使用Xlib,我使用的是cgo,所以我的header是:
// #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] byte
对于 C 结构类型来说是非常错误的,但我无法弄清楚发生了什么。如果这有帮助,C 库中的 XEvent 结构如下所示:
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;
As Go doesn't have support for C's union type in the general case, C's union types are represented as a Go byte array with the same length.
另一个问题:Golang CGo: converting union field to Go type
或者 a go-nuts mailing list post 可能会有进一步的帮助。
简而言之,您将无法简单地使用或简单地与使用联合的 C 代码交互。至少你需要设置类似 unsafe.Pointer
的东西来手动操作 field/type 并且你的示例看起来特别烦人(即它不仅仅是上面几种不同类型整数的联合关联案例是)。
鉴于这些名称,我的印象是您可能希望在 Go 中创建一个 "event" 接口,并将每个所需的事件类型实现为实现该接口的 Go 类型。然后编写代码(在 Go 或 C 中)根据 Go "union"/[] 字节的前 C.sizeof(int)
字节转换 to/from C 联合(我认为第一个 int type
字段可能包含在每个 if X… 事件类型中)。
我正在 Golang 中创建一个简单的 window 管理器(代码基于 tinywm 中的 c 代码)。为了使用Xlib,我使用的是cgo,所以我的header是:
// #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] byte
对于 C 结构类型来说是非常错误的,但我无法弄清楚发生了什么。如果这有帮助,C 库中的 XEvent 结构如下所示:
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;
As Go doesn't have support for C's union type in the general case, C's union types are represented as a Go byte array with the same length.
另一个问题:Golang CGo: converting union field to Go type
或者 a go-nuts mailing list post 可能会有进一步的帮助。
简而言之,您将无法简单地使用或简单地与使用联合的 C 代码交互。至少你需要设置类似 unsafe.Pointer
的东西来手动操作 field/type 并且你的示例看起来特别烦人(即它不仅仅是上面几种不同类型整数的联合关联案例是)。
鉴于这些名称,我的印象是您可能希望在 Go 中创建一个 "event" 接口,并将每个所需的事件类型实现为实现该接口的 Go 类型。然后编写代码(在 Go 或 C 中)根据 Go "union"/[] 字节的前 C.sizeof(int)
字节转换 to/from C 联合(我认为第一个 int type
字段可能包含在每个 if X… 事件类型中)。