Übergabe von Funktionszeigern an C-Code mit cgo
Ab Go v1.6 hat cgo die Regeln für die Übergabe von Zeigern an C-Code geändert. Die frühere Methode zum Aufrufen dynamischer Go-Rückrufe aus C-Code, wie im Go-Wiki beschrieben, funktioniert nicht mehr.
Neue Regeln von cgo
cgo verbietet jetzt die Übergabe von Go-Zeigern zu C, wenn der Speicher, auf den sie verweisen, selbst Go-Zeiger enthält. Diese Einschränkung wird zur Laufzeit erzwungen und führt bei Verletzung zu Programmabstürzen.
Überwindung der Limita
Trotz der neuen Einschränkung gibt es mehrere Möglichkeiten, Zeiger auf C-Code zu übertragen unter Einhaltung der auferlegten Regeln. Ein gängiger Ansatz besteht darin, eine synchronisierte Datenstruktur zu speichern, die eindeutige IDs und tatsächliche Zeiger abbildet. Dies ermöglicht die Übertragung von IDs an den C-Code anstelle von direkten Zeigern.
Codelösung
Der folgende Codeausschnitt zeigt eine Lösung für das Problem:
<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>
Dieser Code entspricht den aktualisierten Richtlinien der Wiki-Seite und bietet eine praktikable Lösung für die Übergabe von Funktionszeigern an C-Code gemäß den neuen CGO-Regeln.
Das obige ist der detaillierte Inhalt vonWie kann ich nach den Änderungen in Go v1.6 mithilfe von cgo Funktionszeiger an C-Code in Go übergeben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!