【发布时间】:2018-12-31 03:44:31
【问题描述】:
我一直在玩 GLFW 绑定,我想通过 glfw.SetUserPointer(...) 将 Queue 结构传递给它,
因此,我这样传递它:
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.
但是,我的结构中没有指针,我很困惑:(
【问题讨论】:
-
Values是一个切片,其中包含一个指针。 Go slice 在 C 中并不是很有用,你打算用它做什么? -
好吧,我打算使用循环队列来存储回调函数中的事件,方法是使用 getuserpointer 检索它并避免全局变量,这就是我在 C 中至少这样做的方式
-
C 代码是否需要使用循环缓冲区,是否需要特定的结构?如果 C 代码完全使用该结构,它需要与 C 兼容。如果您需要通过一个不透明的结构,但需要在 Go 中实现它,也许使用包级别的变量,并将其封装在单独的包中够了。