winapi的GetSystemTimes函数无法填充lpIdleTime/lpKernelTime/lpUserTime参数。

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

winapi GetSystemTimes function does not fill lpIdleTime/lpKernelTime/lpUserTime

问题

我被卡在GetSystemTimes函数上了。C++代码没有任何问题,但是用golang时,我得到了三个nil值,而不是预期的值。

我的代码:

package main

import (
	"log"
	"syscall"
	"unsafe"
)

var (
	modKernel32 = syscall.NewLazyDLL("kernel32.dll")
	procGetSystemTimes = modKernel32.NewProc("GetSystemTimes")
)

type SystemTimes struct {
	IdleTime   *syscall.Filetime
	KernelTime *syscall.Filetime
	UserTime   *syscall.Filetime
}

func main() {
	times, err := getSystemTimes()
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("idle=%v, kernel=%v, user=%v", times.IdleTime, times.KernelTime, times.UserTime)
}

func getSystemTimes() (times SystemTimes, err error) {
	res, _, err1 := procGetSystemTimes.Call(uintptr(unsafe.Pointer(times.IdleTime)), uintptr(unsafe.Pointer(times.KernelTime)), uintptr(unsafe.Pointer(times.UserTime)))
	if res != 1 {
		return times, err1
	}
	return
}

这非常简单,非常类似于stdlib中的syscall的GetProcessTimes函数。
看一下,我的程序打印出来的是:

idle=<nil>, kernel=<nil>, user=<nil>

为什么?我期望得到错误或结果,为什么我的字段是空的?

配置:win8 x64,go1.4.2 windows/amd64

英文:

I`m stuck with GetSystemTimes function. There is no any problem in c++ code, but with golang I'm getting three nils instead of expected values

My code:

package main

import (
	"log"
	"syscall"
	"unsafe"
)

var (
	modKernel32 = syscall.NewLazyDLL("kernel32.dll")
	procGetSystemTimes = modKernel32.NewProc("GetSystemTimes")
)

type SystemTimes struct {
	IdleTime   *syscall.Filetime
	KernelTime *syscall.Filetime
	UserTime   *syscall.Filetime
}

func main() {
	times, err := getSystemTimes()
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("idle=%v, kernel=%v, user=%v", times.IdleTime, times.KernelTime, times.UserTime)
}

func getSystemTimes() (times SystemTimes, err error) {
	res, _, err1 := procGetSystemTimes.Call(uintptr(unsafe.Pointer(times.IdleTime)), uintptr(unsafe.Pointer(times.KernelTime)), uintptr(unsafe.Pointer(times.UserTime)))
	if res != 1 {
		return times, err1
	}
	return
}

It's super simple and very similar to syscall`s GetProcessTimes function from stdlib.
And look, what my program prints:

idle=<nil>, kernel=<nil>, user=<nil>

Why? I expect error or result, why my fields are empty?

Confguration: win8 x64, go1.4.2 windows/amd64

答案1

得分: 2

您正在将空字段的地址传递给函数。

要么直接将其指向Filetime结构体,要么在传递之前初始化这3个字段:

type SystemTimes struct {
    IdleTime   syscall.Filetime
    KernelTime syscall.Filetime
    UserTime   syscall.Filetime
}
......
res, _, err1 := procGetSystemTimes.Call(uintptr(unsafe.Pointer(&times.IdleTime)), uintptr(unsafe.Pointer(&times.KernelTime)), uintptr(unsafe.Pointer(&times.UserTime)))

输出:

┌─ oneofone@Oa [/tmp]
└──➜ env CC=i686-w64-mingw32-gcc CGO_ENABLED=1 GOOS=windows GOARCH=386 go build -a /tmp/syscall.go; and wine syscall.exe
2015/05/09 22:31:53 idle={1292275456 39}, kernel={1436840864 41}, user={3496565408 2}

playground

英文:

You're passing the address of nil fields to the function.

Either make it point directly to the Filetime struct or initialize all 3 fields before passing them:

type SystemTimes struct {
	IdleTime   syscall.Filetime
	KernelTime syscall.Filetime
	UserTime   syscall.Filetime
}
.....
res, _, err1 := procGetSystemTimes.Call(uintptr(unsafe.Pointer(&times.IdleTime)), uintptr(unsafe.Pointer(&times.KernelTime)), uintptr(unsafe.Pointer(&times.UserTime)))

Output:

┌─ oneofone@Oa [/tmp]                                                                                                             
└──➜ env CC=i686-w64-mingw32-gcc CGO_ENABLED=1 GOOS=windows GOARCH=386 go build -a /tmp/syscall.go; and wine syscall.exe
2015/05/09 22:31:53 idle={1292275456 39}, kernel={1436840864 41}, user={3496565408 2}

<kbd>playground</kbd>

huangapple
  • 本文由 发表于 2015年5月10日 04:25:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/30144654.html
匿名

发表评论

匿名网友

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

确定