导出以C类型作为参数的函数[不能在package.Func的参数中使用x(type*C.ctype)作为type*package.C.ctype] 库代码(简化版): //package1.go 包装1 输入“C” func播放(s*C.char){ } 客户端代码: //main.go 包干管 输入“C” 进口( “路径/到/包1” ) func PlayMore(s*C.char){ 包装1.播放(s) } func main(){ } 生成错误: #命令行参数 main.go:12:无法将s(type*C.char)用作type*package1.C.char 在package1的参数中。播放
似乎“C”包是每个包的本地包,编译器将它们视为不同的包。我试过这样的方法:导出以C类型作为参数的函数[不能在package.Func的参数中使用x(type*C.ctype)作为type*package.C.ctype] 库代码(简化版): //package1.go 包装1 输入“C” func播放(s*C.char){ } 客户端代码: //main.go 包干管 输入“C” 进口( “路径/到/包1” ) func PlayMore(s*C.char){ 包装1.播放(s) } func main(){ } 生成错误: #命令行参数 main.go:12:无法将s(type*C.char)用作type*package1.C.char 在package1的参数中。播放,go,cgo,Go,Cgo,似乎“C”包是每个包的本地包,编译器将它们视为不同的包。我试过这样的方法: func PlayMore(s*package1.C.char){ 包装1.播放(s) } 但这是一个语法错误 问题: 如何使代码编译 更多信息: 在原始问题中,参数类型不是*C.char。它是指向遗留库中的C类型的指针 package1具有低级API和高级API: 低级API只是用Go语法包装了C签名。参数和返回类型为C.xxx类型 高级API为遗留库提供了一个纯Go接口,这意味着没有C.xxx参数或返回类型。
func PlayMore(s*package1.C.char){
包装1.播放(s)
}
但这是一个语法错误
问题:
- 如何使代码编译
*C.char
。它是指向遗留库中的C类型的指针
package1
具有低级API和高级API:
- 低级API只是用Go语法包装了C签名。参数和返回类型为
类型C.xxx
- 高级API为遗留库提供了一个纯Go接口,这意味着没有
参数或返回类型。例如,使用C.xxx
代替string
。实现准备参数,并为实际工作调用低级API*C.char
main
包)实际上是另一个包(package2
),可以从C调用。您可以将其视为构建在另一个C库之上的C库,但实现是用Go编写的。例如,上面的PlayMore()
在原始问题中通过//export PlayMore
导出,以便可以从C调用
当package2
需要调用旧式库提供的函数时,它会调用package1
的低级API。事实上,package1
的低级API之所以是公共的,是为了允许像package2
这样的包重用它
相关问题:
您可以导出:
类型ExportedType C.char
,如以下工作示例代码:
软件包1
输入“C”
输入“fmt”
类型ExportedType C.char
func播放(s*ExportedType){
fmt.Println(C.GoString((*C.char)(s)))
}
主要代码:
主程序包
输入“C”
进口(
“路径/到/包1”
)
func PlayMore(s*C.char){
package1.播放((*package1.ExportedType)(s))
}
func main(){
PlayMore(C.CString(“Hi”))
}
输出:
Hi
谢谢但是如果用指针类型替换
C.char
,这似乎不起作用。在最初的问题中,上面的C.char
实际上是一个指向不透明类型的指针。@siu ching pong asuka kenji是的,完全用在这种样式中。我的意思是上面的代码是实际代码的简化版本。在最初的问题中,它不是C端的const char*
。它是“指向不透明类型的指针”。通过不透明类型,它意味着struct
已声明但未定义,如下所示:struct\u otype;typedef结构_otype*otype;无效播放(otype*x)代码>。因此,x
是有效的“指向指向结构类型“”的指针。”。在最初的问题中,也涉及函数指针,所以事情变得有点复杂。它现在似乎不起作用,但让我稍微调整一下,看看它是否起作用;otype o={0};otype*p=&o;o类型**q=&p;*/import“C”import“fmt”type ExportedType C.otype func Play(s**ExportedType){fmt.Println(“Hi”)}
和func main(){var t*package1.ExportedType p:=&t package1.Play(p)}
otype
由遗留库声明,而不是由我正在编写的Go包装器声明,因此我无法控制它。该类型是不透明的,这意味着传统库中的头不定义结构的大小和布局,因此它并不总是16字节。使用不透明类型是使其“平台独立”的C方式。结构的详细信息取决于供应商。