使用cgo 將函數指標傳遞給C 程式碼
從Go v1.6 開始,cgo 改變了將指標傳遞給C 程式碼的規則。 Go wiki 中概述的從 C 程式碼呼叫動態 Go 回呼的先前方法不再有效。
cgo 的新規則
cgo 現在禁止傳遞 Go 指標如果它們引用的記憶體本身包含任何 Go 指針,則指向 C。此限制在運行時強制執行,如果違反,則會導致程式崩潰。
克服限制
儘管有新的限制,但仍有多種方法可以將指標傳送到 C 程式碼同時遵守強加的規則。一種常見的方法涉及儲存在唯一 ID 和實際指標之間映射的同步資料結構。這樣可以將 ID 傳輸到 C 代碼,而不是直接指標。
程式碼解決方案
以下程式碼片段示範了該問題的解決方案:
<code class="go">package main import ( "fmt" "sync" ) // Declare a function to be invoked by C code. func MyCallback(x int) { fmt.Println("callback with", x) } func Example() { i := register(MyCallback) // Register the callback function and obtain its ID. C.CallMyFunction(C.int(i)) // Pass the ID to the C function. unregister(i) // Deregister the callback function. } // Data structures for registering and deregistering callbacks. var mu sync.Mutex var index int var fns = make(map[int]func(int)) // Register a callback function and return its ID. func register(fn func(int)) int { mu.Lock() defer mu.Unlock() index++ for fns[index] != nil { index++ } fns[index] = fn return index } // Return the callback function associated with a given ID. func lookup(i int) func(int) { mu.Lock() defer mu.Unlock() return fns[i] } // Deregister a callback function using its ID. func unregister(i int) { mu.Lock() defer mu.Unlock() delete(fns, i) } func main() { Example() }</code>
此程式碼符合wiki 頁面的更新指南,並提供了在新的cgo 規則下將函數指標傳遞給C 程式碼的可行解決方案。
以上是Go v1.6 發生更改後,如何使用 cgo 將函數指標傳遞給 Go 中的 C 程式碼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!