如何在cgo中使用extern c字符串
How to use extern c strings in cgo
我试图在 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 版本:go version go1.15.7 linux/amd64
C 中的数组不能由 cgo 透明地处理。
有所谓的地道 Go 将 C 内存映射到 Go 可以自然操作的东西。这是一个工作示例 (main.go
):
package main
import (
"fmt"
"unsafe"
)
// #cgo LDFLAGS: -L${SRCDIR} -la
// #include "./a.h"
import "C"
func main() {
x := 1
fmt.Println(x)
fmt.Println(len(C.s)) // Note, Go has no idea so it says 0.
cStr := (*[1 << 30]*C.char)(unsafe.Pointer(&C.s))[x]
fmt.Println(C.GoString(cStr))
}
关键部分是 (*[1 << 30]*C.char)(unsafe.Pointer(&C.s))
。这表示将 &C.s
解释为一个非常大的常量数组(“对任何人都足够大”......),但只从中提取感兴趣的元素 [x]
。
unsafe.Pointer()
的使用应该是一个警告,即超出实际 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 版本:go version go1.15.7 linux/amd64
C 中的数组不能由 cgo 透明地处理。
有所谓的地道 Go 将 C 内存映射到 Go 可以自然操作的东西。这是一个工作示例 (main.go
):
package main
import (
"fmt"
"unsafe"
)
// #cgo LDFLAGS: -L${SRCDIR} -la
// #include "./a.h"
import "C"
func main() {
x := 1
fmt.Println(x)
fmt.Println(len(C.s)) // Note, Go has no idea so it says 0.
cStr := (*[1 << 30]*C.char)(unsafe.Pointer(&C.s))[x]
fmt.Println(C.GoString(cStr))
}
关键部分是 (*[1 << 30]*C.char)(unsafe.Pointer(&C.s))
。这表示将 &C.s
解释为一个非常大的常量数组(“对任何人都足够大”......),但只从中提取感兴趣的元素 [x]
。
unsafe.Pointer()
的使用应该是一个警告,即超出实际 C 数组末尾的查找将产生不可预测的结果。实际上,它可能会导致程序崩溃。