登录
首页 >  Golang >  Go问答

传递 Go 指针给 Cgo

来源:stackoverflow

时间:2024-03-23 16:36:30 223浏览 收藏

传递 Go 指针给 Cgo 时,Go 内存中不能包含任何 Go 指针。本文探讨了传递复杂数据结构时遇到的“cgo argument has go pointer to go pointer”错误。解决方案是展平数据,而不是传递整个结构,并将数组元素转换为 C 类型。然而,建议在必要时谨慎使用混合语言实现复杂数据结构,并考虑在不同语言中完全实现或使用替代概念。

问题内容

我一直在研究 glfw 绑定,我想通过 glfw.setuserpointer(...) 向其传递一个队列结构,

因此,我传递这样的内容:

type circularqueue struct {
    values      []interface{}
    front, rear int32
    capacity    int32
}

func newcircularqueue(capacity int32) *circularqueue {
    if capacity < 1 {
        log.fatal("capacity of circular queue zero or negative")
    }

    queue := &circularqueue{capacity: capacity}
    queue.values = make([]interface{}, capacity)
    return queue
}

...
events := newcircularqueue(16)
window.setuserpointer(unsafe.pointer(events))

但是我收到运行时错误,

panic: runtime error: cgo argument has go pointer to go pointer

我做了一些挖掘,看起来......我引用:

Go code may pass a Go pointer to C provided the Go memory to which it 
points does not contain any Go pointers. The C code must preserve this 
property: it must not store any Go pointers in Go memory, even temporarily. 
When passing a pointer to a field in a struct, the Go memory in question is 
the memory occupied by the field, not the entire struct. When passing a 
pointer to an element in an array or slice, the Go memory in question is the 
entire array or the entire backing array of the slice.

但是,我的结构中没有指针,我很困惑:(


解决方案


解决方案非常简单。您必须将提供给 c 代码的内容展平。不要传递循环队列,而是传递数据。

//C
int mysterious_c_func(const char* values, front int32_t, back int32_t, capacity int32_t);

// Go
type CircularQueue struct {
    Values      []char //this can't possibly work with interface.
    Front, Rear int32
    Capacity    int32
}
...
var q CircularQueue
data := (*C.char)(unsafe.Pointer(q.values))
C.mysterious_c_func(data, C.int(queue.Front), C.int(queue.Rear), C.int(queue.Capacity))

但真正的问题是你试图部分用 c 部分用 go 实现一个复杂的数据结构。要么实现循环缓冲区

  1. 支持两种语言,并允许从数组进行构造。
  2. 仅在您真正需要该概念的地方。

本篇关于《传递 Go 指针给 Cgo》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>