首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在cgo中使用extern c字符串

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

Stack Overflow用户
提问于 2021-04-22 07:49:11
回答 1查看 154关注 0票数 2

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

a.h文件:

代码语言:javascript
复制
extern const char *s[];

a.c文件:

代码语言:javascript
复制
const char *s[] = {"a", "b", "c"};

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

main.go文件:

代码语言:javascript
复制
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]))
}

然后我使用命令运行代码。

代码语言:javascript
复制
go run main.go

我发现了一个错误:

代码语言:javascript
复制
panic: runtime error: index out of range [0] with length 0

怎么修呢?谢谢

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-24 23:57:34

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

有一种被称为惯用的Go将C内存映射到Go可以自然操作的东西。下面是一个工作示例(main.go):

代码语言:javascript
复制
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数组结束后,会产生不可预测的结果。事实上,它可能会使程序崩溃。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67208983

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档