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()