Heim > Artikel > Backend-Entwicklung > Wie übergebe ich Funktionszeiger an C-Code mit cgo After Go v1.6?
Übergabe von Funktionszeigern an C-Code mit cgo
Vor Go v1.6 erlaubte cgo die Übergabe von Go-Zeigern an C-Code. Nach den in Version 1.6 implementierten Änderungen haben sich die Regeln für die Übergabe von Zeigern jedoch erheblich geändert. Diese Änderung machte die zuvor verwendete Methode zum Aufrufen dynamischer Go-Rückrufe aus C-Code unwirksam.
Problembeschreibung
Das Codebeispiel, einst ein Funktionsbeispiel für den Aufruf eines Go-Rückrufs von C, führt nun zu einem Laufzeitfehler:
panic: runtime error: cgo argument has Go pointer to Go pointer
Lösung
Unter den neuen CGO-Regeln darf Go-Code nur dann einen Go-Zeiger auf C übergeben, wenn der Der Go-Speicher, auf den er zeigt, enthält keine Go-Zeiger. Diese Einschränkung verhindert die Weitergabe von Zeigern an C-Code, wenn der Speicher, auf den verwiesen wird, Go-Funktions-/Methodenzeiger speichert.
Um diese Einschränkung zu überwinden, können mehrere Ansätze in Betracht gezogen werden. Eine gängige Lösung besteht darin, eine synchronisierte Datenstruktur zu speichern, die eine Entsprechung zwischen bestimmten IDs und den tatsächlichen Zeigern herstellt. Durch die Übergabe der ID an den C-Code anstelle des Zeigers wird die Einschränkung umgangen.
Ein aktualisiertes Codebeispiel, das diese Lösung zeigt:
<code class="go">package gocallback import ( "fmt" "sync" ) /* extern void go_callback_int(int foo, int p1); */ import "C" var mu sync.Mutex var index int var fns = make(map[int]func(C.int)) func register(fn func(C.int)) int { mu.Lock() defer mu.Unlock() index++ for fns[index] != nil { index++ } fns[index] = fn return index } func lookup(i int) func(C.int) { mu.Lock() defer mu.Unlock() return fns[i] } func unregister(i int) { mu.Lock() defer mu.Unlock() delete(fns, i) } //export go_callback_int func go_callback_int(foo C.int, p1 C.int) { fn := lookup(int(foo)) fn(p1) } func MyCallback(x C.int) { fmt.Println("callback with", x) } func Example() { i := register(MyCallback) C.go_callback_int(C.int(i), 5) unregister(i) } func main() { Example() }</code>
Diese Lösung folgt der aktualisierten Wiki-Seite und bietet a Robuster Ansatz zur Übergabe von Funktionszeigern an C-Code innerhalb der aktuellen CGO-Einschränkungen.
Das obige ist der detaillierte Inhalt vonWie übergebe ich Funktionszeiger an C-Code mit cgo After Go v1.6?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!