简介
Go 1.6 引入了修改通过 cgo 将指针传递给 C 代码的规则。因此,以前从 C 代码调用动态 Go 回调的可行方法不再有效。本文探讨了更新后的指南,并演示了如何在当前 Go 生态系统中有效地将函数指针传递给 C 代码。
Go 1.6 中传递函数指针
从 Go 开始1.6,以下规则适用:
Go 代码可以将 Go 指针传递给 C,只要它指向的 Go 内存不包含任何 Go 指针。
此限制源于运行时检查监控违规行为并在检测到时引发崩溃。设置环境变量 GODEBUG=cgocheck=0 会暂时禁用这些检查,但在未来的 Go 版本中可以将其删除。
后果和解决方案
新规则禁止通过如果指向的内存保存 Go 函数/方法指针,则指向 C 代码的指针。有几种方法可以规避此限制:
同步和 ID 对应
一种策略涉及维护将 ID 映射到实际指针的同步数据结构。通过将 ID 传递给 C 代码而不是直接指针,您可以绕过限制,同时仍然实现所需的功能。
示例代码
以下代码片段说明了如何实现这种方法:
<code class="go">import ( "fmt" "sync" ) 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] }</code>
此代码定义了一个注册表系统,该系统为 Go 函数分配唯一的 ID,并以线程安全的方式存储映射。调用 C 代码时,可以直接传递 ID,而不是直接传递函数指针。
结论
Go 1.6 中的变化,在向 C 传递函数指针时需要仔细考虑代码。通过采用上述同步技术,您可以有效克服新的限制并确保与最新版本的 Go 的兼容性。
以上是考虑到新的限制,如何在 Go 1.6 中将函数指针传递给 C 代码?的详细内容。更多信息请关注PHP中文网其他相关文章!