Maison >développement back-end >Golang >Comment puis-je transmettre des pointeurs de fonction vers le code C dans Go 1.6 compte tenu des nouvelles restrictions ?

Comment puis-je transmettre des pointeurs de fonction vers le code C dans Go 1.6 compte tenu des nouvelles restrictions ?

Linda Hamilton
Linda Hamiltonoriginal
2024-11-02 15:43:02446parcourir

How can I pass function pointers to C code in Go 1.6  given the new restrictions?

Passer des pointeurs de fonction au code C à l'aide de cgo : traiter les modifications d'exécution dans Go 1.6

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn