【问题标题】:How to iterate through a c-array如何遍历 c 数组
【发布时间】:2020-11-17 08:29:15
【问题描述】:

在 go 中,我正在尝试遍历在 C 中创建的数组。我有数组的长度 (int arrc) 及其指针 (mytype *arrv)。

我找到了一种方法,但是它涉及在 go 和 c 之间来回传输,并且超级超级hacky。

// void *nextelement(void *p, int i, int size) {
//      return (void*)((uint64_t)p+i*size);
// }
#import "C"

...

    for i := 0; i < protoc; i++ {
        adr := (*C.mytype)(C.nextelement(unsafe.Pointer(myarr), C.int(i), C.sizeof_mytype))


所有这些代码只是为了得到myarr[i]...感觉不对。

【问题讨论】:

  • 更新:使用此逻辑运行并进行一些测试后,代码会出现不可预知的恐慌(换句话说,未定义的行为)。所以我发布的解决方案甚至不起作用。
  • 通常的技巧是获取指向数组第一个元素的指针并将其转换为切片:stackoverflow.com/q/48756732/1256452
  • @torek / JimB,这正是我想要的。你们中的一个人应该回答被接受。

标签: go cgo


【解决方案1】:

注意:这只是从CGo documentation 复制而来。

Turning C arrays into Go slices

C 数组通常以 null 结尾或保留长度 其他地方。

Go 提供了以下函数来从一个新的 Go 字节切片 C 数组:

func C.GoBytes(cArray unsafe.Pointer, length C.int) []byte

创建一个由 C 数组支持的 Go 切片(不复制原始 数据),需要在运行时获取此长度并使用类型 转换为指向一个非常大的数组的指针,然后将其切片到 你想要的长度(如果你使用 Go,还记得设置上限 1.2 或更高版本),例如(有关可运行示例,请参阅http://play.golang.org/p/XuC0xqtAIC):

        var theCArray *C.YourType = C.getTheArray()
        length := C.getTheArrayLength()
        slice := (*[1 << 28]C.YourType)(unsafe.Pointer(theCArray))[:length:length]

请记住,Go 垃圾收集器不会 与这些数据进行交互,并且如果它从 C 端释放出来 事情,任何使用切片的 Go 代码的行为是 不确定性。

魔术数组大小常量的原因在What does (*[1 << 30]C.YourType) do exactly in CGo?中有描述。常量的实际值,无论是1 &lt;&lt; 30还是1 &lt;&lt; 28或其他什么,并不重要,但它必须至少与最大的length 值将是。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-19
    • 2011-10-30
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多