aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/runtime/cgo/handle.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/runtime/cgo/handle.go')
-rw-r--r--libgo/go/runtime/cgo/handle.go39
1 files changed, 37 insertions, 2 deletions
diff --git a/libgo/go/runtime/cgo/handle.go b/libgo/go/runtime/cgo/handle.go
index 720acca..d711900 100644
--- a/libgo/go/runtime/cgo/handle.go
+++ b/libgo/go/runtime/cgo/handle.go
@@ -59,6 +59,41 @@ import (
// void myprint(uintptr_t handle) {
// MyGoPrint(handle);
// }
+//
+// Some C functions accept a void* argument that points to an arbitrary
+// data value supplied by the caller. It is not safe to coerce a cgo.Handle
+// (an integer) to a Go unsafe.Pointer, but instead we can pass the address
+// of the cgo.Handle to the void* parameter, as in this variant of the
+// previous example:
+//
+// package main
+//
+// /*
+// extern void MyGoPrint(void *context);
+// static inline void myprint(void *context) {
+// MyGoPrint(context);
+// }
+// */
+// import "C"
+// import (
+// "runtime/cgo"
+// "unsafe"
+// )
+//
+// //export MyGoPrint
+// func MyGoPrint(context unsafe.Pointer) {
+// h := *(*cgo.Handle)(context)
+// val := h.Value().(string)
+// println(val)
+// h.Delete()
+// }
+//
+// func main() {
+// val := "hello Go"
+// h := cgo.NewHandle(val)
+// C.myprint(unsafe.Pointer(&h))
+// // Output: hello Go
+// }
type Handle uintptr
// NewHandle returns a handle for a given value.
@@ -70,7 +105,7 @@ type Handle uintptr
//
// The intended use is to pass the returned handle to C code, which
// passes it back to Go, which calls Value.
-func NewHandle(v interface{}) Handle {
+func NewHandle(v any) Handle {
h := atomic.AddUintptr(&handleIdx, 1)
if h == 0 {
panic("runtime/cgo: ran out of handle space")
@@ -83,7 +118,7 @@ func NewHandle(v interface{}) Handle {
// Value returns the associated Go value for a valid handle.
//
// The method panics if the handle is invalid.
-func (h Handle) Value() interface{} {
+func (h Handle) Value() any {
v, ok := handles.Load(uintptr(h))
if !ok {
panic("runtime/cgo: misuse of an invalid Handle")