1 package cgo
2 3 import (
4 "sync"
5 "unsafe"
6 )
7 8 // #include <stdlib.h>
9 import "C"
10 11 // refMap is a convenient way to store opaque references that can be passed to
12 // C. It is useful if an API uses function pointers and you cannot pass a Go
13 // pointer but only a C pointer.
14 type refMap struct {
15 refs map[unsafe.Pointer]interface{}
16 lock sync.Mutex
17 }
18 19 // Put stores a value in the map. It can later be retrieved using Get. It must
20 // be removed using Remove to avoid memory leaks.
21 func (m *refMap) Put(v interface{}) unsafe.Pointer {
22 m.lock.Lock()
23 defer m.lock.Unlock()
24 if m.refs == nil {
25 m.refs = make(map[unsafe.Pointer]interface{}, 1)
26 }
27 ref := C.malloc(1)
28 m.refs[ref] = v
29 return ref
30 }
31 32 // Get returns a stored value previously inserted with Put. Use the same
33 // reference as you got from Put.
34 func (m *refMap) Get(ref unsafe.Pointer) interface{} {
35 m.lock.Lock()
36 defer m.lock.Unlock()
37 return m.refs[ref]
38 }
39 40 // Remove deletes a single reference from the map.
41 func (m *refMap) Remove(ref unsafe.Pointer) {
42 m.lock.Lock()
43 defer m.lock.Unlock()
44 delete(m.refs, ref)
45 C.free(ref)
46 }
47