CGO指针值已更改



我使用 cgo 绑定了 C api(子弹物理引擎(,一些函数使用数据指针。这个想法是,我可以将指针附加到对象,并在物理引擎调用回调时检索它。我的问题是,当我取回价值时,它会改变,我没有这样做。似乎没有源代码明确更改该值。

碰撞对象:源、标头、与该类交互的 go 代码

以下是我发送值的方式,重新转换为 *int 和 int 很好,打印了正确的数字:

num := x*amounty*amountz + y*amountz + z + 1
ptr := unsafe.Pointer(&num)
fmt.Printf("created %v %vn", ptr, *(*int)(ptr))
rb := sphere.RigidBody(ptr, 1)

但是当我从射线测试中取回它时,值发生了变化:

ptr := hit.GetUserPointer()
log.Printf("we got back: %v %v", ptr, *(*int)(ptr))
指针

值本身没有改变,我可以抬头看到有一个指针指向这个位置,但它指向的值是不同的。

现在我想知道也许 go 没有清理值(垃圾回收(,因为它将不再使用并用其他东西替换此内存位置。

示例输出(删除垃圾值(:

created: 0xc2080006e0 40
2014/11/07 17:10:01  we got back: 0xc2080006e0 4921947622888946315

任何指针(呵呵(都值得赞赏:)

Go 的

垃圾收集器不知道 C 或 C++ 代码持有的指针,因此没有什么可以让 num 变量保持活动状态。

可以通过在 Go 变量中存储指针的第二个副本来解决此问题。 一种方法是使用类型为 map[*C.some_c_type]*int 或类似的全局变量,并将&num也存储在那里。 请记住使用互斥锁保护映射,以便在并发访问时正常运行。

为了不泄漏,当基础 C 代码不再包含对它的引用时,您需要从映射中手动删除&num。 如果 C 库提供了在存储用户指针时设置 destroy 通知函数的功能,这将很容易:只需将 Go 函数导出到 C 并将其用作通知函数即可。 如果没有,但 Go 绑定知道指针何时完成(例如,如果 RigidBody 变量始终通过 Go API 释放,则可以在那里进行清理。

最新更新