为什么Go C类型来自不同模块时会有所不同?

时间:2017-11-05 00:36:04

标签: go cgo

在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,它会突然发挥作用。 / p>

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

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

1 个答案:

答案 0 :(得分:2)

  

Command cgo

     

Go references to C

     

Cgo将C类型转换为等效的未导出的Go类型。因为   翻译是未导出的,Go包不应该暴露C.   导出的API中的类型:一个Go包中使用的C类型   不同于另一种使用的相同C类型。

你说,“出于某种原因,编译器认为C.int不等于module.C.int。”正如cgo命令文档所解释的那样,不同包中未导出的Go类型不相等。

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

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