Passer des pointeurs de fonction vers le code C à l'aide de cgo
Avant Go v1.6, cgo autorisait le passage de pointeurs Go vers le code C. Cependant, après les changements implémentés dans la v1.6, les règles de passage des pointeurs ont considérablement changé. Cette modification a rendu inefficace la méthode précédemment utilisée pour appeler des rappels Go dynamiques à partir du code C.
Description du problème
L'exemple de code, autrefois un exemple fonctionnel d'appel d'un rappel Go à partir de C, entraîne désormais une erreur d'exécution :
panic: runtime error: cgo argument has Go pointer to Go pointer
Solution
En vertu des nouvelles règles cgo, le code Go peut transmettre un pointeur Go vers C uniquement si le La mémoire Go vers laquelle elle pointe ne contient aucun pointeur Go. Cette restriction empêche de passer des pointeurs vers du code C si la mémoire pointée stocke des pointeurs de fonction/méthode Go.
Pour surmonter cette limitation, plusieurs approches peuvent être envisagées. Une solution courante consiste à stocker une structure de données synchronisée qui établit une correspondance entre des identifiants spécifiques et les pointeurs réels. En transmettant l'ID au code C au lieu du pointeur, la restriction est contournée.
Un exemple de code mis à jour présentant cette solution :
<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>
Cette solution suit la page wiki mise à jour, fournissant un approche robuste pour transmettre des pointeurs de fonction vers le code C dans le cadre des contraintes cgo actuelles.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!