为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕尼黑8549860 2022-08-24 18:40:50
我正在尝试在 go 程序的 c 库中使用 c 字符串,但发生错误:a.h文件:extern const char *s[];a.c文件:const char *s[] = {"a", "b", "c"};我将这两个文件编译为liba.amain.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
查看完整描述

1 回答

?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

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]


使用 应该是一个警告,即超出实际 C 数组的末尾将产生不可预测的结果。实际上,它可能会使程序崩溃。unsafe.Pointer()


查看完整回答
反对 回复 2022-08-24
  • 1 回答
  • 0 关注
  • 77 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信