package main /* #cgo CFLAGS: -fPIC #cgo pkg-config: Qt5Widgets #include "binding.h" */ import "C" import ( "runtime/cgo" "unsafe" ) func CArray(data []string) (C.int, **C.char) { c_argv := (*[0xfff]*C.char)(C.malloc(C.ulong(8 /* sizeof pointer */ * len(data)))) for i, arg := range data { c_argv[i] = C.CString(arg) } return C.int(len(data)), (**C.char)(unsafe.Pointer(c_argv)) } type CallbackFunc func(argc C.int, args *C.void) //export miqt_exec_callback func miqt_exec_callback(cb *C.void, argc C.int, args *C.void) { // Our CABI for all callbacks is void(int, void*). // Our Go ABI is CallbackFunc // Then the Go bindings can unmarshal the arguments and C.free() them as necessary cfunc, ok := (cgo.Handle(uintptr(unsafe.Pointer(cb))).Value()).(CallbackFunc) if !ok { panic("miqt: callback of non-callback type (heap corruption?)") } cfunc(argc, args) } // type QApplication struct { h C.PQApplication } func NewQApplication(args []string) *QApplication { argc, argv := CArray(args) h := C.QApplication_new(&argc, argv) return &QApplication{h: h} } func (this *QApplication) Exec() int { ret := C.QApplication_exec(this.h) return int(ret) } // type QWidget struct { h C.PQWidget } func (this *QWidget) CPointer() C.PQWidget { if this == nil { return nil } return this.h } func NewQWidget() *QWidget { ret := C.QWidget_new() return &QWidget{h: ret} } func (this *QWidget) Show() { C.QWidget_show(this.h) } // type QPushButton struct { h C.PQPushButton } func NewQPushButton(label string, parent *QWidget) *QPushButton { h := C.QPushButton_new(C.CString(label), parent.CPointer()) return &QPushButton{h: h} } func (this *QPushButton) Show() { C.QPushButton_show(this.h) } func (this *QPushButton) AsQWidget() *QWidget { return &QWidget{h: C.PQWidget(this.h)} // Type cast } func (this *QPushButton) OnPressed(cb func()) { var cbWrapper CallbackFunc = func(argc C.int, args *C.void) { // Unmarshal arguments // Pressed() doesn't take any, though cb() } C.QPushButton_connect_pressed(this.h, unsafe.Pointer(uintptr(cgo.NewHandle(cbWrapper)))) // TODO allow disconnect'ing, or tie lifespan for handle.Delete(), ... }