This repository was archived by the owner on Jan 28, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpointers.go
More file actions
49 lines (43 loc) · 1.29 KB
/
pointers.go
File metadata and controls
49 lines (43 loc) · 1.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package cl12
// #include "api.h"
import "C"
import (
"runtime/cgo"
"unsafe"
)
// userData contains a dynamically allocated memory that holds a cgo.Handle .
// This type is necessary to safely transport the value of a handle across.
//
// The example for cgo.Handle showcases to transport the pointer to the handle value - yet the value
// the pointer points to can (and will) go out of scope for callbacks for which this userData is intended.
// As the handle value itself is not allowed to be directly cast into an unsafe.Pointer, the value needs
// to be stored in an allocated memory block. Incidentally, this memory block has then a pointer that can
// be used as actual C-land user data.
type userData struct {
ptr *C.uintptr_t
}
func userDataFor(v any) (userData, error) {
ptr := (*C.uintptr_t)(C.malloc((C.size_t)(unsafe.Sizeof(C.uintptr_t(0)))))
if ptr == nil {
return userData{}, ErrOutOfMemory
}
h := cgo.NewHandle(v)
*ptr = C.uintptr_t(h)
return userData{ptr: ptr}, nil
}
func userDataFrom(ptr *C.uintptr_t) userData {
return userData{ptr: ptr}
}
func (data userData) Value() any {
h := cgo.Handle(*data.ptr)
return h.Value()
}
func (data userData) Delete() {
if data.ptr == nil {
return
}
h := cgo.Handle(*data.ptr)
h.Delete()
C.free(unsafe.Pointer(data.ptr))
data.ptr = nil
}