Heim  >  Artikel  >  Backend-Entwicklung  >  Wie kann ich nach den Änderungen in Go v1.6 mithilfe von cgo Funktionszeiger an C-Code in Go übergeben?

Wie kann ich nach den Änderungen in Go v1.6 mithilfe von cgo Funktionszeiger an C-Code in Go übergeben?

Susan Sarandon
Susan SarandonOriginal
2024-11-03 22:13:31662Durchsuche

How can I pass function pointers to C code in Go using cgo after the changes in Go v1.6?

Übergabe von Funktionszeigern an C-Code mit cgo

Ab Go v1.6 hat cgo die Regeln für die Übergabe von Zeigern an C-Code geändert. Die frühere Methode zum Aufrufen dynamischer Go-Rückrufe aus C-Code, wie im Go-Wiki beschrieben, funktioniert nicht mehr.

Neue Regeln von cgo

cgo verbietet jetzt die Übergabe von Go-Zeigern zu C, wenn der Speicher, auf den sie verweisen, selbst Go-Zeiger enthält. Diese Einschränkung wird zur Laufzeit erzwungen und führt bei Verletzung zu Programmabstürzen.

Überwindung der Limita

Trotz der neuen Einschränkung gibt es mehrere Möglichkeiten, Zeiger auf C-Code zu übertragen unter Einhaltung der auferlegten Regeln. Ein gängiger Ansatz besteht darin, eine synchronisierte Datenstruktur zu speichern, die eindeutige IDs und tatsächliche Zeiger abbildet. Dies ermöglicht die Übertragung von IDs an den C-Code anstelle von direkten Zeigern.

Codelösung

Der folgende Codeausschnitt zeigt eine Lösung für das Problem:

<code class="go">package main

import (
    "fmt"
    "sync"
)

// Declare a function to be invoked by C code.
func MyCallback(x int) {
    fmt.Println("callback with", x)
}

func Example() {
    i := register(MyCallback) // Register the callback function and obtain its ID.
    C.CallMyFunction(C.int(i)) // Pass the ID to the C function.
    unregister(i) // Deregister the callback function.
}

// Data structures for registering and deregistering callbacks.
var mu sync.Mutex
var index int
var fns = make(map[int]func(int))

// Register a callback function and return its ID.
func register(fn func(int)) int {
    mu.Lock()
    defer mu.Unlock()
    index++
    for fns[index] != nil {
        index++
    }
    fns[index] = fn
    return index
}

// Return the callback function associated with a given ID.
func lookup(i int) func(int) {
    mu.Lock()
    defer mu.Unlock()
    return fns[i]
}

// Deregister a callback function using its ID.
func unregister(i int) {
    mu.Lock()
    defer mu.Unlock()
    delete(fns, i)
}

func main() {
    Example()
}</code>

Dieser Code entspricht den aktualisierten Richtlinien der Wiki-Seite und bietet eine praktikable Lösung für die Übergabe von Funktionszeigern an C-Code gemäß den neuen CGO-Regeln.

Das obige ist der detaillierte Inhalt vonWie kann ich nach den Änderungen in Go v1.6 mithilfe von cgo Funktionszeiger an C-Code in Go übergeben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn