GoLang / CGO:从Go中调用Mach API host_statistics()时出现问题

3

我使用以下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头文件中定义如下:

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

我找不到问题的根源,但将var host_info_out类型从C.host_info_t更改为C.integer_t对我有用。 - Kavu
1个回答

1
函数原型表明,host_statistics 的第三个参数是一个 host_info_t 变量,而在你的示例程序中,你正在传递一个指向 host_info_t 变量的指针。

查看 mach/host_info.h 头文件,我们可以看到 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包来在不兼容的指针类型之间进行强制转换。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接