如何在 cgo 中使用 extern c 字符串

我正在尝试在 go 程序的 c 库中使用 c 字符串,但发生错误:


a.h文件:


extern const char *s[];

a.c文件:


const char *s[] = {"a", "b", "c"};

我将这两个文件编译为liba.a


main.go文件:


package main


// #cgo LDFLAGS: -L${SRCDIR} -la

// #include"a.h"

import "C"

import "fmt"


func main() {

        x := 1

        fmt.Println(x)

        fmt.Println(len(C.s))

        fmt.Println(C.GoString(C.s[x]))

}

然后我用命令运行代码


go run main.go

我得到错误:


panic: runtime error: index out of range [0] with length 0

如何解决?谢谢


转到版本:go version go1.15.7 linux/amd64


慕尼黑8549860
浏览 92回答 1
1回答

江户川乱折腾

C 中的数组不是由 cgo 透明处理的。有一种叫做惯用语Go的东西,它将C内存映射到Go可以自然操纵的东西上。下面是一个工作示例 ():main.gopackage mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "unsafe")// #cgo LDFLAGS: -L${SRCDIR} -la// #include "./a.h"import "C"func main() {&nbsp; &nbsp; x := 1&nbsp; &nbsp; fmt.Println(x)&nbsp; &nbsp; fmt.Println(len(C.s)) // Note, Go has no idea so it says 0.&nbsp; &nbsp; cStr := (*[1 << 30]*C.char)(unsafe.Pointer(&C.s))[x]&nbsp; &nbsp; fmt.Println(C.GoString(cStr))}关键部分是.这说明的是一个非常大的恒定大小数组(“对任何人来说都足够大”......),但只从中提取感兴趣的元素。(*[1 << 30]*C.char)(unsafe.Pointer(&C.s))&C.s[x]使用 应该是一个警告,即超出实际 C 数组的末尾将产生不可预测的结果。实际上,它可能会使程序崩溃。unsafe.Pointer()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go