【问题标题】:Trouble using exported function type with C types as parameters使用带有 C 类型作为参数的导出函数类型时遇到问题
【发布时间】:2017-04-12 13:54:20
【问题描述】:

编辑:感谢@Not_a_Golfer,更改了标题以更好地反映问题

我一直在用 Go 做实验,无法解决这个问题。

当它包含在主包中时,以下内容可以正常工作:

// Define a callback-function type, and define an invoker for it
type Callback func(i C.int, d C.double)
func Invoke(cb Callback, i C.int, d C.double) {
        cb(i, d)
}
//... then define my callback and pass it into the invoker
func foo(i C.int, d C.double) {
        fmt.Printf("i %d d %f\n", i, d)
}
func main() {
        Invoke(foo, 2, 2.2)
}

但是当我在一个包中定义 type CallbackInvoke 时,将包导入 main 并调用 mypkg.Invoker(foo, 2, 2.2) 我得到以下构建错误:

src/hello/hello.go:9: cannot convert foo (type func(C.int, C.double)) to type mypkg.Callback

编辑:这里是 hello 包的主要代码。我对所有内容进行了结构化,以便可以使用go 命令进行构建/安装:

package main
import "C"
import "mypkg"
import "fmt"
func foo(i C.int, d C.double) {
        fmt.Printf("i %d d %f\n", i, d)
}
func main() {
        mypkg.Invoke( mypkg.Callback(foo), 2, 2.2 )
}

有人知道对于从包中导出的类型是否有什么特别需要做的吗?我在参数中使用 C 类型,因为最终这将成为 C 库的包装器,我只是想确保 C 类型不是将我的回调函数与回调类型匹配的问题的一部分。

这是包代码:

package mypkg
import "C"
import "fmt"
type Callback func(i C.int, d C.double)
func Invoke(cb Callback, i C.int, d C.double) {
        fmt.Println("Calling cb\n")
        cb( i, d )
}

【问题讨论】:

  • 正如我在已删除的答案中所写,这是 C 包独有的东西,不是一般问题,如果您将 Callback 的签名更改为使用本机 go 类型,一切都会正常工作。我不知道确切的原因,但也许您应该更改标题或其他内容。
  • 更新:它似乎是在函数中使用了 C 类型,因为它与 go intfloat32 一起使用。当我停止使用 Callback 类型并仅将 Invoke 更改为采用 func (C.int,C.double) 类型的参数时,我收到此错误:src/hello/hello.go:9: cannot use foo (type func(C.int, C.double)) as type func(mypkg.C.int, mypkg.C.double) in argument to mypkg.Invoke
  • @Not_a_Golfer,是的,这是有道理的。我不知道您的答案为何被删除,但感谢您的帮助。
  • 我自己删除了它,因为它回答了你最初的问题(你没有强制转换)但没有解决你的问题。
  • 你应该。我在 C 文档中没有发现任何说明导致此问题的原因,但我怀疑它涉及幕后进行的代码生成,每个包的 C 命名空间可能不一样。

标签: go cgo


【解决方案1】:

它们实际上是不同的类型!

将您的代码更改为:

package main

import "C"
import "mypkg"

func main() {
    a := 1

    mypkg.Inc(C.int(a))
}

mypkg:

package mypkg

import "C"

func Inc(a C.int) C.int {
    return a + 1
}

编译第一个包会报错: ./test.go:9:不能在 mypkg.Inc 的参数中使用 C.int(a)(类型 C.int)作为类型 mypkg.C.int

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-03
    • 1970-01-01
    • 2013-01-22
    相关资源
    最近更新 更多