Cgo让c和go 手牵手

go 里面的 cgo 包可以直接调用 c 代码,只需要遵守一定的使用规则即可,对于那些熟悉 c/c++ 的开发者来说,不失为一个福音。

三个代表

cgo 会从 go 代码中去寻找 c/c++ 代码,约定:

紧挨在上面的所有 c 风格的注释语句都可以被 go 编译。

1.所有代码都写在一个 go 文件中

这是最简便的方式,适用于 c 代码逻辑比较简单的情况。

2.c 代码和 go 代码写在独立文件

像这种直接编译 c 源码和 go 源码的方式,只需执行,cgo 会在当前目录或 c 语言 编译参数指定的目录寻找需要的

,文件。

3.go 代码调用动态链接库

如果只提供了 c 的动态链接库和头文件,那么需要在 go 文件中指定 cgo 的 等编译选项:

go 引用 c

C 里面的标准类型可以在 go 里面直接引用:

引用 struct,union,enum:

Go 里面的 struct 不能包含 C 类型。

sizeof:

c 中结构体字段如果是 go 里面的关键字,那么可以在该结构体字段名前面加个 来引用,比如:

Cgo 将 C 类型转译成对应的 go 类型是不可导出的,因此,go 包导出的 API 里面不能含有 C 类型。

C 里面的函数执行结果可以赋给 go 里面的多返回值(执行结果和可能产生的错误值),即使是没有返回值的 类型函数。

cgo 目前还不支持直接调用 C 里面的函数指针,你可以声明一个包含 C 函数指针的 go 变量(如下的 ),这样就可以在 go 和 C 之间传递了。

在 C 里面, 如果一个函数接受一个数组参数,只需要传递数组名即可,但在 go 里面不行,你必须显示指定数组首元素的地址:

下面是几组 c 和 go 之间拷贝数据的语法:

c 引用 go

使用 导出 Go 代码

在 C 代码里面使用 关键字引用 go 代码

传递指针

go 是一门垃圾回收语言,垃圾回收器需要知道每个指针所指向的内存位置,正因为如此,在 go 和 c 之间传递指针有些许限制。

go 指针:使用 操作符或 函数返回的指针

c 指针: 使用 返回的指针

首先,我们需要明白:

将指针传递给 struct 某个字段时,所涉及的 Go 内存是该字段占用的内存,而不是整个结构体占有的内存;将指针传递给数组或切片中的元素时,所涉及的 Go 内存是整个数组或整个切片的底层数组。

go 代码可以传递 go 指针给 c, 前提是这个指针指向的内存不包含任何 go 指针。c 代码必须保留这个属性:

它不能在 go 内存中存储任何 go 指针(即使是临时变量也不行)。

C 代码调用的 Go 函数可能会将 C 指针作为参数,并且可能通过这些指针存储非指针或 C 指针数据,但是它可能不会将 Go 指针存储在由C 指针指向的内存中;C 代码调用的 Go 函数可能会将 Go 指针作为参数,但它必须保留“指向的 Go 内存不包含任何 Go 指针”的属性。

Go 代码可能不会在 C 内存中存储 Go 指针,C 代码可能会在 C 内存中存储 Go 指针,这取决于上面的规则:当 C 函数返回时,它必须停止存储 Go 指针。

References

https://blog.golang.org/c-go-cgo

https://golang.org/cmd/cgo/

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180112G0GDA500?refer=cp_1026

相关快讯

扫码关注云+社区