go + cgo and linking

匿名 (未验证) 提交于 2019-12-03 08:46:08

问题:

i want to use the following c as Go's cgo:

#include <X11/extensions/scrnsaver.h>  main() {   XScreenSaverInfo *info = XScreenSaverAllocInfo();   Display *display = XOpenDisplay(0);    XScreenSaverQueryInfo(display, DefaultRootWindow(display), info);   printf("%u ms\n", info->idle); } 

build with:

gcc -o idle printXIdleTime.c -lX11 -lXss 

i re-wrote that code for Go's cgo:

package tools  // #cgo pkg-config: x11 // #include <X11/extensions/scrnsaver.h> import "C"  func GetIdleTime() (idleTime uint32) {     var info *C.XScreenSaverInfo     var display *C.Display       info = C.XScreenSaverAllocInfo()     display = C.XOpenDisplay(0)      defaultRootWindow := C.XDefaultRootWindow(display)      C.XScreenSaverQueryInfo(display, defaultRootWindow, info)     idleTime = info.idle      return } 

tried to compile with:

go build -gccgoflags="-lXss -lX11" 

however i'm getting linker errors:

/tmp/go-build076004816/opensource.stdk/lib/tools/_obj/x11.cgo2.o: In function _cgo_c0e279f6f16e_Cfunc_XScreenSaverAllocInfo': ./x11.go:52: undefined reference toXScreenSaverAllocInfo' /tmp/go-build076004816/opensource.stdk/lib/tools/_obj/x11.cgo2.o: In function _cgo_c0e279f6f16e_Cfunc_XScreenSaverQueryInfo': ./x11.go:65: undefined reference toXScreenSaverQueryInfo' collect2: error: ld returned 1 exit status

what am i doing wrong?

回答1:

This is how I got it to build. Note the #cgo LDFLAGS line which is probably what you are missing. I had to make a few other changes to make it build. It seems to be returning the right answer on my Linux machine!

package tools  // #cgo LDFLAGS: -lXss -lX11 // #include <X11/extensions/scrnsaver.h> import "C"  func GetIdleTime() (idleTime uint32) {     var info *C.XScreenSaverInfo     var display *C.Display      info = C.XScreenSaverAllocInfo()     display = C.XOpenDisplay(nil)      defaultRootWindow := C.XDefaultRootWindow(display)      C.XScreenSaverQueryInfo(display, C.Drawable(defaultRootWindow), info)     idleTime = uint32(info.idle)      return } 


回答2:

Note that this can be done with the native X Go Binding and the ScreenSaver extension:

package main  import (     "fmt"     "log"      "github.com/BurntSushi/xgb"     "github.com/BurntSushi/xgb/xproto"     "github.com/BurntSushi/xgb/screensaver" )  func main() {     X, err := xgb.NewConn()     if err != nil {         log.Fatal(err)     }      if err = screensaver.Init(X); err != nil {         log.Fatal(err)     }      root := xproto.Setup(X).DefaultScreen(X).Root     info, err := screensaver.QueryInfo(X, xproto.Drawable(root)).Reply()     if err != nil {         log.Fatal(err)     }      fmt.Printf("Idle: %d\n", info.MsSinceUserInput) } 

Outputs:

[andrew@Liger go] go run xscreensaver_idle.go  Idle: 1040 


文章来源: go + cgo and linking
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!