首頁  >  文章  >  後端開發  >  Go v1.6 發生更改後,如何使用 cgo 將函數指標傳遞給 Go 中的 C 程式碼?

Go v1.6 發生更改後,如何使用 cgo 將函數指標傳遞給 Go 中的 C 程式碼?

Susan Sarandon
Susan Sarandon原創
2024-11-03 22:13:31666瀏覽

How can I pass function pointers to C code in Go using cgo after the changes in Go v1.6?

使用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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn