runtime/cgo: clarify Handle documentation

Fixes #45427

Change-Id: Ic67630a5f39d8789a4a30c6b4ee30946bc50382e
Reviewed-on: https://go-review.googlesource.com/c/go/+/308230
Trust: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Ainar Garipov <gugl.zadolbal@gmail.com>
Reviewed-by: Changkun Ou <euryugasaki@gmail.com>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
This commit is contained in:
Ian Lance Taylor 2021-04-07 15:22:53 -07:00
parent bb76193a7f
commit 7e583806d8

View file

@ -9,50 +9,56 @@ import (
"sync/atomic" "sync/atomic"
) )
// Handle provides a safe representation of Go values to pass between // Handle provides a way to pass values that contain Go pointers
// Go and C. The zero value of a handle is not a valid handle, and thus // (pointers to memory allocated by Go) between Go and C without
// is safe to use as a sentinel in C APIs. // breaking the cgo pointer passing rules. A Handle is an integer
// value that can represent any Go value. A Handle can be passed
// through C and back to Go, and Go code can use the Handle to
// retrieve the original Go value.
// //
// The underlying type of Handle is guaranteed to fit in an integer type // The underlying type of Handle is guaranteed to fit in an integer type
// that is large enough to hold the bit pattern of any pointer. // that is large enough to hold the bit pattern of any pointer. The zero
// value of a Handle is not valid, and thus is safe to use as a sentinel
// in C APIs.
//
// For instance, on the Go side: // For instance, on the Go side:
// //
// package main // package main
// //
// /* // /*
// #include <stdint.h> // for uintptr_t // #include <stdint.h> // for uintptr_t
// //
// extern void MyGoPrint(uintptr_t handle); // extern void MyGoPrint(uintptr_t handle);
// void myprint(uintptr_t handle); // void myprint(uintptr_t handle);
// */ // */
// import "C" // import "C"
// import "runtime/cgo" // import "runtime/cgo"
// //
// //export MyGoPrint // //export MyGoPrint
// func MyGoPrint(handle C.uintptr_t) { // func MyGoPrint(handle C.uintptr_t) {
// h := cgo.Handle(handle) // h := cgo.Handle(handle)
// val := h.Value().(int) // val := h.Value().(string)
// println(val) // println(val)
// h.Delete() // h.Delete()
// } // }
// //
// func main() { // func main() {
// val := 42 // val := "hello Go"
// C.myprint(C.uintptr_t(cgo.NewHandle(val))) // C.myprint(C.uintptr_t(cgo.NewHandle(val)))
// // Output: 42 // // Output: hello Go
// } // }
// //
// and on the C side: // and on the C side:
// //
// #include <stdint.h> // for uintptr_t // #include <stdint.h> // for uintptr_t
// //
// // A Go function // // A Go function
// extern void MyGoPrint(uintptr_t handle); // extern void MyGoPrint(uintptr_t handle);
// //
// // A C function // // A C function
// void myprint(uintptr_t handle) { // void myprint(uintptr_t handle) {
// MyGoPrint(handle); // MyGoPrint(handle);
// } // }
type Handle uintptr type Handle uintptr
// NewHandle returns a handle for a given value. // NewHandle returns a handle for a given value.