Spec-Zone.ru › Go

Пакет cgo

  • import "runtime/cgo"
  • Обзор
  • Указатель

Обзор

Пакет cgo содержит поддержку во время выполнения для кода, сгенерированного инструментом cgo. Подробные сведения об использовании cgo см. в документации команды cgo.

Указатель

  • тип Handle
  • func NewHandle(v any) Handle
  • func (h Handle) Delete()
  • func (h Handle) Value() any
  • тип Incomplete

Файлы пакета

callbacks.go callbacks_traceback.go callbacks_unix.go cgo.go clearenv.go handle.go iscgo.go linux.go mmap.go setenv.go sigaction.go

тип Handle

Handle позволяет передавать значения, содержащие указатели Go (указатели на память, выделенную Go), между Go и C, не нарушая правил передачи указателей cgo. Handle — это целочисленное значение, которое может представлять любое значение Go. Handle можно передать через C обратно в Go, а код Go может использовать Handle для получения исходного значения Go.

Гарантируется, что базовый тип Handle помещается в целочисленный тип, достаточно большой для хранения битового представления любого указателя. Нулевое значение Handle недопустимо, поэтому его безопасно использовать в качестве маркера в API C.

Например, на стороне Go:

package main

/*
#include <stdint.h> // for uintptr_t

extern void MyGoPrint(uintptr_t handle);
void myprint(uintptr_t handle);
*/
import "C"
import "runtime/cgo"

//export MyGoPrint
func MyGoPrint(handle C.uintptr_t) {
	h := cgo.Handle(handle)
	val := h.Value().(string)
	println(val)
	h.Delete()
}

func main() {
	val := "hello Go"
	C.myprint(C.uintptr_t(cgo.NewHandle(val)))
	// Output: hello Go
}

и на стороне C:

#include <stdint.h> // for uintptr_t

// A Go function
extern void MyGoPrint(uintptr_t handle);

// A C function
void myprint(uintptr_t handle) {
    MyGoPrint(handle);
}

Некоторые функции C принимают аргумент void*, указывающий на произвольное значение данных, предоставленное вызывающей стороной. Небезопасно преобразовывать Handle (целое число) в unsafe.Pointer Go. Вместо этого можно передать адрес cgo.Handle параметру void*, как в этом варианте предыдущего примера.

Обратите внимание: как описано в документации cmd/cgo, код C не должен сохранять копию полученного указателя Go, если только память не закреплена явно с помощью runtime.Pinner. Этот пример корректен, поскольку функция C myprint не сохраняет копию указателя.

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)
	// In this example, unsafe.Pointer(&h) is valid because myprint
	// does not keep a copy of the pointer. If the C code keeps the
	// pointer after the call returns, use runtime.Pinner to pin it.
	C.myprint(unsafe.Pointer(&h))
	// Output: hello Go
}
type Handle uintptr

func NewHandle

func NewHandle(v any) Handle

NewHandle возвращает дескриптор для заданного значения.

Дескриптор действителен до тех пор, пока программа не вызовет для него Delete. Дескриптор использует ресурсы, и этот пакет предполагает, что код C может хранить дескриптор, поэтому программа должна явно вызвать Delete, когда дескриптор больше не нужен.

Предполагается, что возвращённый дескриптор передаётся коду C, который передаёт его обратно в Go, где вызывается Value.

func (Handle) Delete

func (h Handle) Delete()

Delete делает дескриптор недействительным. Этот метод следует вызывать только тогда, когда программе больше не нужно передавать дескриптор в C и у кода C больше нет копии значения дескриптора.

Если дескриптор недействителен, метод вызывает панику.

func (Handle) Value

func (h Handle) Value() any

Value возвращает связанное значение Go для действительного дескриптора.

Если дескриптор недействителен, метод вызывает панику.

тип Incomplete

Incomplete используется специально для семантики неполных типов C.

type Incomplete struct {
    // contains filtered or unexported fields
}

© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/runtime/cgo/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API