cgo指针值已更改

时间:2014-11-07 22:14:41

标签: pointers go bullet cgo

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

CollisionObject:sourceheaderThe 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)表示赞赏:)

1 个答案:

答案 0 :(得分:1)

Go的垃圾收集器不知道C或C ++代码所持有的指针,因此没有任何东西可以使num变量保持活动状态。

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

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