使用 CGO 将函数指针传递给 C 代码
简介
之前的 Go 版本1.6 中,使用 CGO 将函数指针传递给 C 代码非常简单。然而,随着 Go 1.6 中新规则的引入,这种做法变得更加复杂。
问题
问题的症结在于更新的 CGO 规则,它规定 Go 代码只能将 Go 指针传递给 C,如果它们引用的内存不包含任何其他 Go 指针。这会产生一个问题,因为函数指针存储在可能包含其他 Go 指针的 Go 内存中。
潜在解决方案
已经出现了几种解决此问题的方法。一种常见的解决方案是完全放弃使用直接函数指针。相反,创建一个同步数据结构,将 ID(整数)映射到实际的函数指针。这允许您将 ID 传递给 C 代码而不是指针本身。
示例实现
以下代码片段演示了如何实现此方法:
<code class="golang">package gocallback import ( "fmt" "sync" ) type Callback func(C.int) var mu sync.Mutex var index int var fns = make(map[int]Callback) func register(fn Callback) int { mu.Lock() defer mu.Unlock() index++ for fns[index] != nil { index++ } fns[index] = fn return index } func lookup(i int) Callback { mu.Lock() defer mu.Unlock() return fns[i] } func unregister(i int) { mu.Lock() defer mu.Unlock() delete(fns, i) }</code>
C 代码中的用法
Go 数据结构就位后,您可以通过传递 ID 而不是函数指针来从 C 代码调用 Go 回调本身。例如:
<code class="c">extern void go_callback_int(int foo, int p1); static inline void CallMyFunction(int foo) { go_callback_int(foo, 5); }</code>
结论
虽然新的 CGO 规则增加了将函数指针传递给 C 代码的过程的一些复杂性,但本文概述的方法提供有效的解决方案。通过利用同步的数据结构和 ID,您可以继续享受 Go 和 C 代码之间接口的好处,同时遵守最新的 CGO 法规。
以上是如何在 Go 版本 1.6 及更高版本中使用 CGO 将函数指针传递给 C 代码?的详细内容。更多信息请关注PHP中文网其他相关文章!