导出以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类型作为参数的函数[不能在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参数或返回类型。

似乎“C”包是每个包的本地包,编译器将它们视为不同的包。我试过这样的方法:

func PlayMore(s*package1.C.char){
包装1.播放(s)
}
但这是一个语法错误

问题:
  • 如何使代码编译
更多信息: 在原始问题中,参数类型不是
*C.char
。它是指向遗留库中的C类型的指针

package1
具有低级API和高级API:

  • 低级API只是用Go语法包装了C签名。参数和返回类型为
    C.xxx
    类型
  • 高级API为遗留库提供了一个纯Go接口,这意味着没有
    C.xxx
    参数或返回类型。例如,使用
    string
    代替
    *C.char
    。实现准备参数,并为实际工作调用低级API
上面的客户机代码(
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方式。结构的详细信息取决于供应商。