英文:
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 <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:
XScreenSaverAllocInfo'
> undefined reference to
> /tmp/go-build076004816/opensource.stdk/lib/tools/_obj/x11.cgo2.o: In
> function _cgo_c0e279f6f16e_Cfunc_XScreenSaverQueryInfo': ./x11.go:65:
XScreenSaverQueryInfo' collect2: error: ld
> undefined reference to
> 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 <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
得分: 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 (
"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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论