go + cgo 和链接

huangapple go评论93阅读模式
英文:

go + cgo and linking

问题

我想将以下C代码作为Go的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);
}

使用以下命令进行构建:

gcc -o idle printXIdleTime.c -lX11 -lXss

我为Go的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
}

尝试使用以下命令进行编译:

go build -gccgoflags="-lXss -lX11"

然而,我遇到了链接器错误:

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

我做错了什么?

英文:

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

#include &lt;X11/extensions/scrnsaver.h&gt;

main() {
  XScreenSaverInfo *info = XScreenSaverAllocInfo();
  Display *display = XOpenDisplay(0);

  XScreenSaverQueryInfo(display, DefaultRootWindow(display), info);
  printf(&quot;%u ms\n&quot;, info-&gt;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 &lt;X11/extensions/scrnsaver.h&gt;
import &quot;C&quot;

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=&quot;-lXss -lX11&quot;

however i'm getting linker errors:

> /tmp/go-build076004816/opensource.stdk/lib/tools/_obj/x11.cgo2.o: In
> function _cgo_c0e279f6f16e_Cfunc_XScreenSaverAllocInfo&#39;: ./x11.go:52:
&gt; undefined reference to
XScreenSaverAllocInfo'
> /tmp/go-build076004816/opensource.stdk/lib/tools/_obj/x11.cgo2.o: In
> function _cgo_c0e279f6f16e_Cfunc_XScreenSaverQueryInfo&#39;: ./x11.go:65:
&gt; undefined reference to
XScreenSaverQueryInfo' collect2: error: ld
> returned 1 exit status

what am i doing wrong?

答案1

得分: 5

这是我构建它的方式。请注意#cgo LDFLAGS行,这可能是你所缺少的。我还必须进行一些其他更改才能构建它。在我的Linux机器上,它似乎返回了正确的答案!

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
}
英文:

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 &lt;X11/extensions/scrnsaver.h&gt;
import &quot;C&quot;
    
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

得分: 2

请注意,这可以通过本地的X Go Binding和ScreenSaver扩展来完成:

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)
}

输出:

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

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

package main

import (
	&quot;fmt&quot;
	&quot;log&quot;

	&quot;github.com/BurntSushi/xgb&quot;
	&quot;github.com/BurntSushi/xgb/xproto&quot;
	&quot;github.com/BurntSushi/xgb/screensaver&quot;
)

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(&quot;Idle: %d\n&quot;, info.MsSinceUserInput)
}

Outputs:

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

huangapple
  • 本文由 发表于 2013年2月13日 06:24:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/14842980.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定