2017-02-27 79 views
3

我是一個相對的新手去。我一直在使用cgo併爲C api構建一個接口。 C api使用註冊回調和一個void* cookie參數來回調。由於垃圾收集,指針會改變Go的值嗎?

下面是一些代碼舉例說明我的問題:

/* 
void cb(void *cookie) { 
    callGo(cookie); 
} 

go_register_cb(void *ptr) { 
    register_cb(&cb, ptr); 
} 
*/ 
import "C" 

import "C" 

//export callGo 
callGo(ptr unsafe.Pointer) { 
    x := (*MyStruct)(ptr) 
    x.doSomething() 
} 

func (x *MyStruct) Start() { 
    C.go_register_cb(unsafe.Pointer(x)) 
} 

此代碼將導致約轉到指針轉到指針運行時錯誤。

我想我明白了在C-land內部保持Go指針的基本含義,即C-land引用不會在垃圾回收器中佔用,所以C最終可能會使用陳舊的引用。

我無法將Go指針傳遞給本身包含Go指針的數據結構的具體要求更令人費解。對我來說唯一有意義的是,由於垃圾回收,Go中的指針可能會改變值(也就是它們指向的地址)。是這樣嗎?

回答

2

這些在Go代碼和C代碼之間傳遞指針的規則在運行時動態檢查。所以當你打破他們的錯誤發生。

而你的猜測是正確的。由於垃圾收集地址被允許改變(指針被更新)。

here from golang.org

即使uintptr持有某個對象的地址,如果物體移動, 也不會是uintptr保持對象被回收垃圾 收集器將不會更新uintptr的價值。

因此,由於gc,移動物體是可能的。