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!