Пакет cgo
Обзор
Пакет cgo содержит поддержку выполнения кода, сгенерированного инструментом cgo. Для получения подробностей об использовании cgo обратитесь к документации команды cgo.
Индекс
Файлы пакета
callbacks.go callbacks_traceback.go cgo.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 не является допустимым и, следовательно, безопасно использовать в качестве контрольного значения в C API.
Например, со стороны 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*, который указывает на произвольное значение данных, предоставленное вызывающим объектом. Небезопасно преобразовывать cgo.Handle (целое число) в Go unsafe.Pointer, но вместо этого мы можем передать адрес cgo.Handle в параметр void*, как показано в этом варианте предыдущего примера:
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
func NewHandle(v any) Handle
NewHandle возвращает дескриптор для заданного значения.
Дескриптор действителен до тех пор, пока программа не вызовет Delete для него. Дескриптор использует ресурсы, и этот пакет предполагает, что код C может удерживать дескриптор, поэтому программа должна явно вызывать Delete, когда дескриптор больше не нужен.
Предполагается, что возвращенный дескриптор будет передан коду C, который передаст его обратно в Go, который вызовет Value.
Функция (Handle) Delete
func (h Handle) Delete()
Delete делает дескриптор недействительным. Этот метод следует вызывать только после того, как программа больше не должна передавать дескриптор в C и код C больше не имеет копии значения дескриптора.
Метод вызывает панику, если дескриптор недействителен.
Функция (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/