mirror of
https://github.com/golang/go
synced 2024-11-26 16:46:58 -07: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 Test31891(t *testing.T) { test31891(t) }
|
||||||
func Test42018(t *testing.T) { test42018(t) }
|
func Test42018(t *testing.T) { test42018(t) }
|
||||||
func Test45451(t *testing.T) { test45451(t) }
|
func Test45451(t *testing.T) { test45451(t) }
|
||||||
|
func Test49633(t *testing.T) { test49633(t) }
|
||||||
func TestAlign(t *testing.T) { testAlign(t) }
|
func TestAlign(t *testing.T) { testAlign(t) }
|
||||||
func TestAtol(t *testing.T) { testAtol(t) }
|
func TestAtol(t *testing.T) { testAtol(t) }
|
||||||
func TestBlocking(t *testing.T) { testBlocking(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.
|
// Issue 45451, bad handling of go:notinheap types.
|
||||||
typedef struct issue45451Undefined issue45451;
|
typedef struct issue45451Undefined issue45451;
|
||||||
|
|
||||||
|
// Issue 49633, example of cgo.Handle with void*.
|
||||||
|
extern void GoFunc49633(void*);
|
||||||
|
void cfunc49633(void *context) { GoFunc49633(context); }
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
@ -113,6 +113,8 @@ typedef struct {
|
|||||||
int i;
|
int i;
|
||||||
} Issue38408, *PIssue38408;
|
} Issue38408, *PIssue38408;
|
||||||
|
|
||||||
|
extern void GoFunc49633(void *context);
|
||||||
|
extern void cfunc49633(void*); // definition is in test.go
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
@ -554,3 +556,26 @@ func GoFunc37033(handle C.uintptr_t) {
|
|||||||
// A typedef pointer can be used as the element type.
|
// A typedef pointer can be used as the element type.
|
||||||
// No runtime test; just make sure it compiles.
|
// No runtime test; just make sure it compiles.
|
||||||
var _ C.PIssue38408 = &C.Issue38408{i: 1}
|
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) {
|
// void myprint(uintptr_t handle) {
|
||||||
// MyGoPrint(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
|
type Handle uintptr
|
||||||
|
|
||||||
// NewHandle returns a handle for a given value.
|
// NewHandle returns a handle for a given value.
|
||||||
|
Loading…
Reference in New Issue
Block a user