首页  >  文章  >  后端开发  >  Go v1.6 发生更改后,如何使用 cgo 将函数指针传递给 Go 中的 C 代码?

Go v1.6 发生更改后,如何使用 cgo 将函数指针传递给 Go 中的 C 代码?

Susan Sarandon
Susan Sarandon原创
2024-11-03 22:13:31666浏览

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

使用 cgo 将函数指针传递给 C 代码

从 Go v1.6 开始,cgo 更改了将指针传递给 C 代码的规则。 Go wiki 中概述的从 C 代码调用动态 Go 回调的先前方法不再有效。

cgo 的新规则

cgo 现在禁止传递 Go 指针如果它们引用的内存本身包含任何 Go 指针,则指向 C。此限制在运行时强制执行,如果违反,则会导致程序崩溃。

克服限制

尽管有新的限制,但仍有多种方法可以将指针传输到 C 代码同时遵守强加的规则。一种常见的方法涉及存储在唯一 ID 和实际指针之间映射的同步数据结构。这样可以将 ID 传输到 C 代码,而不是直接指针。

代码解决方案

以下代码片段演示了该问题的解决方案:

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

此代码符合 wiki 页面的更新指南,并提供了在新的 cgo 规则下将函数指针传递给 C 代码的可行解决方案。

以上是Go v1.6 发生更改后,如何使用 cgo 将函数指针传递给 Go 中的 C 代码?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn