cgo

原文:https://pkg.go.dev/runtime/cgo@go1.23.0

Package cgo contains runtime support for code generated by the cgo tool. See the documentation for the cgo command for details on using cgo.

​ cgo 包含对 cgo 工具生成的代码的运行时支持。有关使用 cgo 的详细信息,请参阅 cgo 命令的文档。

常量

This section is empty.

变量

This section is empty.

函数

This section is empty.

类型

type Handle

1
type Handle uintptr

Handle provides a way to pass values that contain Go pointers (pointers to memory allocated by Go) between Go and C without breaking the cgo pointer passing rules. A Handle is an integer value that can represent any Go value. A Handle can be passed through C and back to Go, and Go code can use the Handle to retrieve the original Go value.

​ Handle 提供了一种在 Go 和 C 之间传递包含 Go 指针(指向 Go 分配的内存的指针)的值的方法,而不会破坏 cgo 指针传递规则。Handle 是一个可以表示任何 Go 值的整数值。Handle 可以通过 C 传递回 Go,Go 代码可以使用Handle 检索原始 Go 值。

The underlying type of Handle is guaranteed to fit in an integer type that is large enough to hold the bit pattern of any pointer. The zero value of a Handle is not valid, and thus is safe to use as a sentinel in C APIs.

​ Handle 的底层类型保证适合于足够大的整数类型,以容纳任何指针的位模式。Handle 的零值无效,因此可以安全地用作 C API 中的哨兵。

For instance, on the Go side:

​ 例如,在 Go 方面:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
}

and on the C side:

​ 而在 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);
}

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:

​ 一些 C 函数接受一个 void* 实参,该参数指向调用者提供的任意数据值。将 cgo.Handle(一个整数)强制转换为 Go unsafe.Pointer 是不安全的,但我们可以将 cgo.Handle 的地址传递给 void* 参数,如下一个示例的变体所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
}

func NewHandle

1
func NewHandle(v any) Handle

NewHandle returns a handle for a given value.

​ NewHandle 为给定值返回一个句柄。

The handle is valid until the program calls Delete on it. The handle uses resources, and this package assumes that C code may hold on to the handle, so a program must explicitly call Delete when the handle is no longer needed.

​ 该句柄有效,直到程序对其调用 Delete。该句柄使用资源,并且此软件包假定 C 代码可能会持有该句柄,因此程序必须在不再需要该句柄时显式调用 Delete。

The intended use is to pass the returned handle to C code, which passes it back to Go, which calls Value.

​ 预期的用途是将返回的句柄传递给 C 代码,C 代码将其传递回 Go,然后调用 Value。

(Handle) Delete

1
func (h Handle) Delete()

Delete invalidates a handle. This method should only be called once the program no longer needs to pass the handle to C and the C code no longer has a copy of the handle value.

​ Delete 使句柄无效。仅当程序不再需要将句柄传递给 C 并且 C 代码不再具有句柄值副本时,才应调用此方法。

The method panics if the handle is invalid.

​ 如果句柄无效,该方法会引发恐慌。

(Handle) Value

1
func (h Handle) Value() any

Value returns the associated Go value for a valid handle.

​ Value 返回有效句柄的关联 Go 值。

The method panics if the handle is invalid.

​ 如果句柄无效,该方法会引发恐慌。

type Incomplete <- go1.20

1
2
3
type Incomplete struct {
	// contains filtered or unexported fields
}

Incomplete is used specifically for the semantics of incomplete C types.

​ Incomplete 专门用于不完整 C 类型的语义。