我使用cgo绑定到C api(子弹物理引擎),一些函数使用数据指针。我的想法是,我可以附加指向对象的指针,并在物理引擎调用回调时稍后检索它。我的问题是,当我获得价值时,它会改变,我没有这样做。似乎没有源代码明确地改变了这个值。
CollisionObject:source,header, The go codes that interracts with that class
如果我发送这些值,重新转换为* int和int就可以了,打印正确的数字:
num := x*amounty*amountz + y*amountz + z + 1
ptr := unsafe.Pointer(&num)
fmt.Printf("created %v %v\n", ptr, *(*int)(ptr))
rb := sphere.RigidBody(ptr, 1)
但是当我从光线测试中得到返回时,值发生了变化:
ptr := hit.GetUserPointer()
log.Printf("we got back: %v %v", ptr, *(*int)(ptr))
指针值本身没有改变,我可以查看并看到有一个指针指向这个位置,但它指向的值是不同的。
现在我想知道是否可能没有清理价值(垃圾收集)因为它不再被使用并用其他东西替换了这个内存位置。
示例输出(删除了垃圾值):
created: 0xc2080006e0 40
2014/11/07 17:10:01 we got back: 0xc2080006e0 4921947622888946315
任何指针(hehe)表示赞赏:)
答案 0 :(得分:1)
num
变量保持活动状态。
您可以通过在Go变量中存储指针的第二个副本来解决此问题。一种方法是使用类型为map[*C.some_c_type]*int
或类似的全局变量,并在那里存储&num
。请记住使用互斥锁保护地图,以便在您具有并发访问权限时正常运行。
为了不泄漏,当底层C代码不再持有对它的引用时,您需要从地图中手动删除&num
。如果C库提供了在存储用户指针时设置销毁通知功能的能力,这将很容易:只需将Go函数导出到C并将其用作通知函数。如果没有,但Go绑定知道指针何时结束(例如,如果始终通过Go API释放RigidBody
变量,则可以在那里进行清理。