Maison  >  Article  >  développement back-end  >  Comment puis-je transmettre des pointeurs de fonction vers le code C à l'aide de CGO dans les versions Go 1.6 et ultérieures ?

Comment puis-je transmettre des pointeurs de fonction vers le code C à l'aide de CGO dans les versions Go 1.6 et ultérieures ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-01 00:01:02705parcourir

How can I pass function pointers to C code using CGO in Go versions 1.6 and later?

Passer des pointeurs de fonction au code C à l'aide de CGO

Introduction

Dans les versions Go antérieures à 1.6, passer des pointeurs de fonction vers le code C à l’aide de CGO était simple. Cependant, avec l'introduction de nouvelles règles dans Go 1.6, cette pratique est devenue plus complexe.

Le problème

Le nœud du problème réside dans les règles CGO mises à jour , qui stipule que le code Go ne peut transmettre des pointeurs Go vers C que si la mémoire à laquelle ils font référence ne contient aucun autre pointeur Go. Cela crée un problème, car les pointeurs de fonction sont stockés dans la mémoire Go qui peut contenir d'autres pointeurs Go.

Solutions potentielles

Plusieurs approches ont émergé pour résoudre ce problème. Une solution courante consiste à abandonner complètement l’utilisation de pointeurs de fonction directs. Au lieu de cela, créez une structure de données synchronisée qui mappe les ID (entiers) aux pointeurs de fonction réels. Cela vous permet de transmettre l'ID au code C au lieu du pointeur lui-même.

Exemple de mise en œuvre

L'extrait de code suivant montre comment implémenter cette approche :

<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>

Utilisation dans le code C

Une fois la structure de données Go en place, vous pouvez appeler le rappel Go à partir du code C en passant l'ID plutôt que le pointeur de fonction lui-même. Par exemple :

<code class="c">extern void go_callback_int(int foo, int p1);

static inline void CallMyFunction(int foo) {
    go_callback_int(foo, 5);
}</code>

Conclusion

Bien que les nouvelles règles CGO ajoutent une certaine complexité au processus de transmission des pointeurs de fonction vers le code C, les approches décrites dans cet article apporter des solutions efficaces. En tirant parti des structures de données et des identifiants synchronisés, vous pouvez continuer à profiter des avantages de l'interfaçage entre le code Go et C tout en respectant les dernières réglementations CGO.

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