Introduction
Go 1.6 a introduit des modifications aux règles de transmission des pointeurs vers le code C via cgo. Par conséquent, les méthodes auparavant viables pour appeler des rappels Go dynamiques à partir du code C ne sont plus fonctionnelles. Cet article explore les directives mises à jour et montre comment transmettre efficacement des pointeurs de fonction au code C dans l'écosystème Go actuel.
Passer des pointeurs de fonction dans Go 1.6
À partir de Go 1.6, la règle suivante s'applique :
Le code Go peut transmettre un pointeur Go vers C à condition que la mémoire Go vers laquelle il pointe ne contient aucun pointeur Go.
Cette restriction découle des contrôles d'exécution qui surveillent les violations et provoquent des crashs lorsqu’ils sont détectés. La définition de la variable d'environnement GODEBUG=cgocheck=0 désactive temporairement ces vérifications, mais leur suppression dans les futures versions de Go est possible.
Conséquences et solutions
La nouvelle règle interdit de passer pointeurs vers le code C si la mémoire pointée contient des pointeurs de fonction/méthode Go. Plusieurs approches existent pour contourner cette limitation :
Synchronisation et correspondance des identifiants
Une stratégie consiste à maintenir une structure de données synchronisée qui mappe les identifiants aux pointeurs réels. En transmettant les identifiants au code C au lieu de pointeurs directs, vous pouvez contourner la restriction tout en obtenant la fonctionnalité souhaitée.
Exemple de code
L'extrait de code suivant illustre comment implémentez cette approche :
<code class="go">import ( "fmt" "sync" ) 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] }</code>
Ce code définit un système de registre qui attribue des identifiants uniques aux fonctions Go et stocke les mappages de manière thread-safe. Lorsque vous appelez du code C, vous pouvez transmettre directement l'ID au lieu du pointeur de fonction.
Conclusion
Les modifications apportées à Go 1.6 nécessitent un examen attentif lors de la transmission de pointeurs de fonction vers C code. En adoptant des techniques de synchronisation comme celle présentée ci-dessus, vous pourrez contourner efficacement les nouvelles restrictions et assurer la compatibilité avec les dernières versions de Go.
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!