我正在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] byte
对于C结构类型是非常错误的。如果这有帮助,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;
答案 0 :(得分:0)
由于Go在一般情况下不支持C的联合类型,因此C的联合类型表示为具有相同长度的Go字节数组。
另一个问题:Golang CGo: converting union field to Go type
或a go-nuts mailing list post可能会有进一步的帮助。
简而言之,您将无法简单地使用或简单地与使用联合的C代码进行交互。至少你需要设置类似unsafe.Pointer
的东西来手动操作字段/类型,你的例子看起来像一个特别讨厌的情况(即它不仅仅是几个不同类型的整数的联合,如上面链接的情况是)。
鉴于名称,我得到的印象是您可能希望在Go中创建一个“事件”界面,并将每个必需的事件类型实现为实现该界面的Go类型。然后根据Go“union”/ [] byte的第一个C.sizeof(int)
字节编写转换为C union的代码(在Go或C中)(我认为第一个int type
字段很可能如果X ...事件类型包含在每个中。