2

I made bindings to a C api (bullet physics engine) using cgo, some functions make use of data pointers. The idea is that I can attach a pointer to an object and retrieve it later when the physics engine invokes a callback. My problem is that when i get the value back, it change and I didn't do it. It seems that no source code is explicitelly changing the value.

CollisionObject: source, header, The go codes that interracts with that class

heres how i send the values, the reconversion to *int and int is fine, the correct numbers are printed:

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)

But when I get it back from a raytest the value changed:

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

the pointer value itself didnt change, i can look up and see that there was a pointer pointing to this location, but the value its pointing at is different.

Now i'm wondering if maybe go didn't clean the value (garbage collected) since it wouldn't be used anymore and replaced this memory location with something else.

example output (with junk values removed):

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

ANY pointer (hehe) is appreciated :)

4

1 回答 1

1

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

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

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

于 2014-11-08T06:25:54.083 回答