Go 语言/CGO : Problems calling Mach API host_statistics() from Go

标签 go cgo mach

我使用以下 C 代码片段来获取 OS X 上的 CPU 负载:

    #include <mach/message.h> 
    #include <mach/mach_host.h>
    #include <mach/host_info.h>

    [...]

    mach_msg_type_number_t  count = HOST_CPU_LOAD_INFO_COUNT;
    kern_return_t error;
    host_cpu_load_info_data_t r_load;

    mach_port_t host_port = mach_host_self();
    error = host_statistics(host_port, HOST_CPU_LOAD_INFO, (host_info_t)&r_load, &count);

看完cgo教程后,我尝试将这段代码移植到Go。生成的代码如下所示:

package main

/*
#include <stdlib.h>
#include <mach/message.h>
#include <mach/mach_host.h>
#include <mach/host_info.h>
*/
import "C"

func main() {
    var err C.kern_return_t
    var host_info_out C.host_info_t
    var host_port C.mach_port_t = C.mach_host_self()

    count := C.mach_msg_type_number_t(C.HOST_CPU_LOAD_INFO_COUNT)

    err = C.host_statistics(C.host_t(host_port), C.HOST_CPU_LOAD_INFO, &host_info_out, &count)
}

但是,当我尝试构建代码时,我得到了以下错误消息

go build cputimes.go 
# command-line-arguments
cputimes.go:33: cannot use &host_info_out (type *_Ctype_host_info_t) as type *_Ctype_integer_t in function argument

我不明白为什么 cgo 会提示这个类型。 host_statistics() 的签名在 mach header 中定义为:

 kern_return_t host_statistics
 (
      host_t host_priv,
      host_flavor_t flavor,
      host_info_t host_info_out,
      mach_msg_type_number_t *host_info_outCnt
 );

最佳答案

函数原型(prototype)说 host_statistics 的第三个参数是一个 host_info_t 变量,而你传递一个指向 host_info_t 变量的指针你的示例程序。

查看 mach/host_info.h header file ,我们可以看到host_info_t是一个指针类型:

typedef integer_t   *host_info_t;       /* varying array of int. */

这就解释了为什么您会收到有关类型与 integer_t 不匹配的错误消息。

在处理该参数时,您的 Go 代码看起来并不等同于 C 代码。您可能想要更像这样的东西:

...
var r_load C.host_cpu_load_info_data_t
...
err = C.host_statistics(C.host_t(host_port), C.HOST_CPU_LOAD_INFO, C.host_info_t(unsafe.Pointer(&r_load)), &count)
...

(您需要使用 unsafe 包在不兼容的指针类型之间进行转换)。

关于Go 语言/CGO : Problems calling Mach API host_statistics() from Go,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19123059/

相关文章:

python - 在 OS X 中运行进程,查找启动进程

Go例程和Defer

go - 如何在for循环中使用所有处理器核心?

go - 你好,戈兰的世界

go - 如何使用来自不同包的相同 C 类型?

c - OSX setgid 系统调用 - 哪个 API 是正确的

go - 如何使用gorm制作外键

c++ - 使用Go + SWIG + C++代码清理内存管理

c++ - cgo : iostream:38:28: fatal error: bits/c++config. h 编译错误:没有那个文件或目录

c - 使用 Mach 信号量代替进程间匿名信号量