首页 > 后端开发 > Golang > Go v1.6 之后如何使用 cgo 将函数指针传递给 C 代码?

Go v1.6 之后如何使用 cgo 将函数指针传递给 C 代码?

Linda Hamilton
发布: 2024-11-01 11:35:29
原创
281 人浏览过

How to Pass Function Pointers to C Code Using cgo After Go v1.6?

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

在 Go v1.6 之前,cgo 允许将 Go 指针传递给 C 代码。然而,在 v1.6 中实现更改后,传递指针的规则发生了显着变化。此更改使得之前从 C 代码调用动态 Go 回调的方法无效。

问题描述

代码示例,曾经是调用 Go 回调的功能示例来自 C,现在会导致运行时错误:

panic: runtime error: cgo argument has Go pointer to Go pointer
登录后复制

解决方案

在新的 cgo 规则下,Go 代码可以仅在以下情况下将 Go 指针传递给 C:它指向的Go内存不包含任何Go指针。如果指向的内存存储 Go 函数/方法指针,此限制会阻止将指针传递给 C 代码。

要克服此限制,可以考虑多种方法。常见的解决方案涉及存储同步数据结构,该数据结构在特定 ID 和实际指针之间建立对应关系。通过将 ID 传递给 C 代码而不是指针,可以绕过限制。

展示此解决方案的更新代码示例:

<code class="go">package gocallback

import (
    "fmt"
    "sync"
)

/*
extern void go_callback_int(int foo, int p1);
*/
import "C"

var mu sync.Mutex
var index int
var fns = make(map[int]func(C.int))

func register(fn func(C.int)) int {
    mu.Lock()
    defer mu.Unlock()
    index++
    for fns[index] != nil {
        index++
    }
    fns[index] = fn
    return index
}

func lookup(i int) func(C.int) {
    mu.Lock()
    defer mu.Unlock()
    return fns[i]
}

func unregister(i int) {
    mu.Lock()
    defer mu.Unlock()
    delete(fns, i)
}

//export go_callback_int
func go_callback_int(foo C.int, p1 C.int) {
    fn := lookup(int(foo))
    fn(p1)
}

func MyCallback(x C.int) {
    fmt.Println("callback with", x)
}

func Example() {
    i := register(MyCallback)
    C.go_callback_int(C.int(i), 5)
    unregister(i)
}

func main() {
    Example()
}</code>
登录后复制

此解决方案遵循更新的 wiki 页面,提供了在当前 cgo 约束内将函数指针传递给 C 代码的稳健方法。

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

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板