Übergabe von Funktionszeigern an C-Code mit CGO
Einführung
In Go-Versionen vor 1.6 war die Übergabe von Funktionszeigern an C-Code mithilfe von CGO unkompliziert. Mit der Einführung neuer Regeln in Go 1.6 ist diese Praxis jedoch komplexer geworden.
Das Problem
Der Kern des Problems liegt in den aktualisierten CGO-Regeln , die festlegen, dass Go-Code Go-Zeiger nur dann an C übergeben kann, wenn der Speicher, auf den sie verweisen, keine anderen Go-Zeiger enthält. Dies führt zu einem Problem, da Funktionszeiger im Go-Speicher gespeichert sind, die möglicherweise andere Go-Zeiger enthalten.
Mögliche Lösungen
Es wurden mehrere Ansätze entwickelt, um dieses Problem anzugehen. Eine gängige Lösung besteht darin, ganz auf die Verwendung direkter Funktionszeiger zu verzichten. Erstellen Sie stattdessen eine synchronisierte Datenstruktur, die IDs (Ganzzahlen) den tatsächlichen Funktionszeigern zuordnet. Dadurch können Sie die ID anstelle des Zeigers selbst an den C-Code übergeben.
Beispielimplementierung
Der folgende Codeausschnitt zeigt, wie dieser Ansatz implementiert wird:
<code class="golang">package gocallback import ( "fmt" "sync" ) type Callback func(C.int) var mu sync.Mutex var index int var fns = make(map[int]Callback) func register(fn Callback) int { mu.Lock() defer mu.Unlock() index++ for fns[index] != nil { index++ } fns[index] = fn return index } func lookup(i int) Callback { mu.Lock() defer mu.Unlock() return fns[i] } func unregister(i int) { mu.Lock() defer mu.Unlock() delete(fns, i) }</code>
Verwendung in C-Code
Once the Go Wenn die Datenstruktur vorhanden ist, können Sie den Go-Rückruf vom C-Code aus aufrufen, indem Sie die ID und nicht den Funktionszeiger selbst übergeben. Zum Beispiel:
<code class="c">extern void go_callback_int(int foo, int p1); static inline void CallMyFunction(int foo) { go_callback_int(foo, 5); }</code>
Fazit
Während die neuen CGO-Regeln den Prozess der Übergabe von Funktionszeigern an C-Code etwas komplexer machen, sind es die in diesem Artikel beschriebenen Ansätze Wirksame Lösungen anbieten. Durch die Nutzung synchronisierter Datenstrukturen und IDs können Sie weiterhin die Vorteile der Schnittstelle zwischen Go- und C-Code nutzen und gleichzeitig die neuesten CGO-Vorschriften einhalten.
Das obige ist der detaillierte Inhalt vonWie kann ich mit CGO in Go-Versionen 1.6 und höher Funktionszeiger an C-Code übergeben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!