mirror of
https://github.com/golang/go
synced 2024-09-06 00:19:45 +00:00
runtime/cgo: add example of Handle with void* parameter
Fixes #49633 Change-Id: I12ca350f7dd6bfc8753a4a169f29b89ef219b035 Reviewed-on: https://go-review.googlesource.com/c/go/+/364774 Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Trust: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
parent
57aba325c8
commit
d2f4c935f2
|
@ -61,6 +61,7 @@ func Test32579(t *testing.T) { test32579(t) }
|
|||
func Test31891(t *testing.T) { test31891(t) }
|
||||
func Test42018(t *testing.T) { test42018(t) }
|
||||
func Test45451(t *testing.T) { test45451(t) }
|
||||
func Test49633(t *testing.T) { test49633(t) }
|
||||
func TestAlign(t *testing.T) { testAlign(t) }
|
||||
func TestAtol(t *testing.T) { testAtol(t) }
|
||||
func TestBlocking(t *testing.T) { testBlocking(t) }
|
||||
|
|
|
@ -915,6 +915,11 @@ void issue40494(enum Enum40494 e, union Union40494* up) {}
|
|||
|
||||
// Issue 45451, bad handling of go:notinheap types.
|
||||
typedef struct issue45451Undefined issue45451;
|
||||
|
||||
// Issue 49633, example of cgo.Handle with void*.
|
||||
extern void GoFunc49633(void*);
|
||||
void cfunc49633(void *context) { GoFunc49633(context); }
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
|
|
|
@ -113,6 +113,8 @@ typedef struct {
|
|||
int i;
|
||||
} Issue38408, *PIssue38408;
|
||||
|
||||
extern void GoFunc49633(void *context);
|
||||
extern void cfunc49633(void*); // definition is in test.go
|
||||
*/
|
||||
import "C"
|
||||
|
||||
|
@ -554,3 +556,26 @@ func GoFunc37033(handle C.uintptr_t) {
|
|||
// A typedef pointer can be used as the element type.
|
||||
// No runtime test; just make sure it compiles.
|
||||
var _ C.PIssue38408 = &C.Issue38408{i: 1}
|
||||
|
||||
// issue 49633, example use of cgo.Handle with void*
|
||||
|
||||
type data49633 struct {
|
||||
msg string
|
||||
}
|
||||
|
||||
//export GoFunc49633
|
||||
func GoFunc49633(context unsafe.Pointer) {
|
||||
h := *(*cgo.Handle)(context)
|
||||
v := h.Value().(*data49633)
|
||||
v.msg = "hello"
|
||||
}
|
||||
|
||||
func test49633(t *testing.T) {
|
||||
v := &data49633{}
|
||||
h := cgo.NewHandle(v)
|
||||
defer h.Delete()
|
||||
C.cfunc49633(unsafe.Pointer(&h))
|
||||
if v.msg != "hello" {
|
||||
t.Errorf("msg = %q, want 'hello'", v.msg)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue