微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决如何在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 版本:go version go1.15.7 linux/amd64

解决方法

cgo 不透明地处理 C 中的数组。

有所谓的惯用 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 数组的末尾将产生不可预测的结果。事实上,它可能会导致程序崩溃。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。