1package pointer 2 3// #include <stdlib.h> 4import "C" 5import ( 6 "sync" 7 "unsafe" 8) 9 10var ( 11 mutex sync.Mutex 12 store = map[unsafe.Pointer]interface{}{} 13) 14 15func Save(v interface{}) unsafe.Pointer { 16 if v == nil { 17 return nil 18 } 19 20 // Generate real fake C pointer. 21 // This pointer will not store any data, but will bi used for indexing purposes. 22 // Since Go doest allow to cast dangling pointer to unsafe.Pointer, we do rally allocate one byte. 23 // Why we need indexing, because Go doest allow C code to store pointers to Go data. 24 var ptr unsafe.Pointer = C.malloc(C.size_t(1)) 25 if ptr == nil { 26 panic("can't allocate 'cgo-pointer hack index pointer': ptr == nil") 27 } 28 29 mutex.Lock() 30 store[ptr] = v 31 mutex.Unlock() 32 33 return ptr 34} 35 36func Restore(ptr unsafe.Pointer) (v interface{}) { 37 if ptr == nil { 38 return nil 39 } 40 41 mutex.Lock() 42 v = store[ptr] 43 mutex.Unlock() 44 return 45} 46 47func Unref(ptr unsafe.Pointer) { 48 if ptr == nil { 49 return 50 } 51 52 mutex.Lock() 53 delete(store, ptr) 54 mutex.Unlock() 55 56 C.free(ptr) 57} 58