【发布时间】: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 Callback 和 Invoke 时,将包导入 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
int和float32一起使用。当我停止使用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 命名空间可能不一样。