github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/runtime/cgo/handle.go (about) 1 // Copyright 2021 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package cgo 6 7 // Handleは、Goで割り当てられたメモリのポインタ(Goのポインタ)を含む値を、 8 // cgoのポインタ渡し規則を破ることなく、GoとCの間でやり取りするための手段を提供します。 9 // Handleは、任意のGoの値を表すことができる整数値です。 10 // Handleは、Cを介してGoに渡すことも、Goのコードで元のGoの値を取得するためにHandleを使用することもできます。 11 // 12 // Handleの基になる型は、ポインタのビットパターンを保持できるだけの十分に大きな整数型に収まることが保証されています。 13 // Handleのゼロ値は無効であり、CのAPIでセンチネルとして安全に使用することができます。 14 // 15 // たとえば、Goの側では: 16 // 17 // package main 18 // 19 // /* 20 // #include <stdint.h> // for uintptr_t 21 // 22 // extern void MyGoPrint(uintptr_t handle); 23 // void myprint(uintptr_t handle); 24 // */ 25 // import "C" 26 // import "runtime/cgo" 27 // 28 // //export MyGoPrint 29 // func MyGoPrint(handle C.uintptr_t) { 30 // h := cgo.Handle(handle) 31 // val := h.Value().(string) 32 // println(val) 33 // h.Delete() 34 // } 35 // 36 // func main() { 37 // val := "hello Go" 38 // C.myprint(C.uintptr_t(cgo.NewHandle(val))) 39 // // Output: hello Go 40 // } 41 // 42 // Cの側では: 43 // 44 // #include <stdint.h> // for uintptr_t 45 // 46 // // A Go function 47 // extern void MyGoPrint(uintptr_t handle); 48 // 49 // // A C function 50 // void myprint(uintptr_t handle) { 51 // MyGoPrint(handle); 52 // } 53 // 54 // 特定のCの関数は、呼び出し元が提供した任意のデータの値を指すvoid*引数を受け入れます。 55 // [cgo.Handle](整数)をGoの [unsafe.Pointer] に強制変換することは安全ではありませんが、 56 // 代わりにcgo.Handleのアドレスをvoid*パラメータに渡すことができます。次に示す前の例のバリアントでは、このようにします。 57 // 58 // package main 59 // 60 // /* 61 // extern void MyGoPrint(void *context); 62 // static inline void myprint(void *context) { 63 // MyGoPrint(context); 64 // } 65 // */ 66 // import "C" 67 // import ( 68 // "runtime/cgo" 69 // "unsafe" 70 // ) 71 // 72 // //export MyGoPrint 73 // func MyGoPrint(context unsafe.Pointer) { 74 // h := *(*cgo.Handle)(context) 75 // val := h.Value().(string) 76 // println(val) 77 // h.Delete() 78 // } 79 // 80 // func main() { 81 // val := "hello Go" 82 // h := cgo.NewHandle(val) 83 // C.myprint(unsafe.Pointer(&h)) 84 // // Output: hello Go 85 // } 86 type Handle uintptr 87 88 // NewHandleは指定された値のハンドルを返します。 89 // 90 // このハンドルはprogramがそれに対してDeleteを呼び出すまで有効です。ハンドルはリソースを使用し、 91 // このパッケージではCコードがハンドルを保持している可能性があるため、プログラムはハンドルが不要になったら 92 // 明示的にDeleteを呼び出す必要があります。 93 // 94 // この関数の意図された使用方法は、返されたハンドルをCコードに渡し、 95 // CコードがそれをGoに戻し、GoがValueを呼び出すことです。 96 func NewHandle(v any) Handle 97 98 // Valueは有効なハンドルに関連付けられたGoの値を返します。 99 // 100 // ハンドルが無効な場合、このメソッドはパニックを発生させます。 101 func (h Handle) Value() any 102 103 // Deleteはハンドルを無効にします。このメソッドは、プログラムがもはやCにハンドルを渡す必要がなくなり、Cのコードがハンドルの値のコピーを持っていない場合にのみ呼び出すべきです。 104 // 105 // ハンドルが無効な場合、このメソッドはパニックを引き起こします。 106 func (h Handle) Delete()