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

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

Susan Sarandon
Susan SarandonOriginal
2024-11-03 22:13:31664browse

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

Passing Function Pointers to C Code with cgo

Starting with Go v1.6, cgo altered the rules for passing pointers to C code. The prior method of invoking dynamic Go callbacks from C code, as outlined in the Go wiki, no longer functions.

cgo's New Rules

cgo now prohibits passing Go pointers to C if the memory they reference contains any Go pointers itself. This restriction is enforced at runtime, resulting in program crashes if violated.

Overcoming the Limita

Despite the new limitation, there are several ways to transfer pointers to C code while adhering to the imposed rules. One common approach involves storing a synchronized data structure that maps between unique IDs and actual pointers. This enables the transfer of IDs to the C code instead of direct pointers.

Code Solution

The following code snippet demonstrates a solution to the issue:

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

This code aligns with the wiki page's updated guidelines and provides a feasible solution to passing function pointers to C code under the new cgo rules.

The above is the detailed content of How can I pass function pointers to C code in Go using cgo after the changes in Go v1.6?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn