为什么来自不同模块的 Go C 类型不同?

Why are Go C types different when they come from different modules?

在 Go 中,由于我无法解释的不兼容类型,我遇到了编译错误。我正在使用 "C" 模块。一个最小示例包含以下 2 个文件:

package module

import "C"

type T struct {
    X C.int
}

和一个主程序

package main

import (
    "fmt"
    "sandbox/module"
)

import "C"

func f() *module.T {
    var x C.int = 42
    return &module.T{X: x}
}

func main() {
    fmt.Printf("value: %d", f().X)
}

这无法编译消息 ./main.go:12: cannot use x (type C.int) as type module.C.int in field value.

出于某种原因,编译器认为 C.int 不等于 module.C.int

它一定与 C 模块以及代码分布在 2 个模块中的事实有关,因为如果我从 C.int 切换到纯 int 它会突然起作用.

为什么这段代码编译不通过?在不将所有代码压缩到一个模块中的情况下使其编译的正确解决方案是什么?

我在 Ubuntu 16.04 上使用最新的 Go 编译器 1.9.2。

Command cgo

Go references to C

Cgo translates C types into equivalent unexported Go types. Because the translations are unexported, a Go package should not expose C types in its exported API: a C type used in one Go package is different from the same C type used in another.

你说,"For some reason the compiler thinks that C.int is not equal to module.C.int."正如cgo命令文档所解释的,不同包中未导出的Go类型是不相等的。

不要在导出的文件中公开 C 类型 API。例如,

module.go:

package module

type T struct {
    X int
}

main.go:

package main

import (
    "fmt"
    "sandbox/module"
)

import "C"

func f() *module.T {
    var x C.int = 42
    return &module.T{X: int(x)}
}

func main() {
    fmt.Printf("value: %d\n", f().X)
}

输出:

value: 42