前提条件:
了解Go语言和C语言的基本知识和基本用法。
一、什么是cgo
简单地说,cgo是在Go语言中使用C语言代码的一种方式。
二、为什么要有cgo
C语言经过数十年发展,经久不衰,各个方面的开源代码、闭源库已经非常丰富。这无疑是一块巨大的宝藏,对于一门现代编程语言而言,如何用好现成的C代码就显得极为重要。
三、如何使用
3.1 系统配置
要想使用cgo,你的计算机上必须有GCC,并且将gcc编译器的可执行文件所在的目录添加到PATH这个环境变量中。例如,我的gcc.exe在C:\mingw64\bin下,所以,要把C:\mingw64\bin这个目录添加到PATH。
3.2 C假包
我们知道,Go语言以包为代码的逻辑单元。如果要在Go代码中使用C代码,也要为C代码单独设立一个“包”并将其导入:
import "C"
C是一个假包,包的性质它一般也有。例如可以用“包名.符号名”的方式使用其中的变量或类型。
var n C.int
这行代码,定义了一个C语言int类型的变量,与用
var conn net.Conn
定义一个net.Conn类型的变量没什么语法上的不同。
如果紧挨着import "C"这行上方,加入连续若干行注释,在注释中编写C代码,这些C代码就作为C包的内容。例如:
/* int PlusOne(int n) { return n + 1; } */ import "C"
在Go代码中就可以调用PlusOne这个函数,再例如:
/* #include <stdio.h> */ import "C"
在Go代码中就可以调用头文件stdio.h中的函数。
除此之外,还可以把你的C源文件放到要使用它的Go源文件的同一目录,然后在C包中包含(include)对应的头文件。例如,我有C源文件ys_origin.c和头文件ys_origin.h,而我要在ys_origin.go中调用ys_origin.c中的函数,那么,我可以这么做:
/* include "ys_origin.h" */ import "C" func FuncOne(a int, b string) error { // ...... C.LevelUp() // ...... }
下面讲解具体用法。
四、具体介绍
C语言的数据结构有数字类型(整数和浮点数)、函数、数组、指针、结构体、联合体,很多第三方库的API函数也要求提供回掉函数。那就一一道来。
4.1 变量(全局变量)
使用C中的全局变量很简单,只要“C.变量名”就可以。
package main /* int g_a = 7; */ import "C" import ( "fmt" ) func TestVar() { fmt.Println(C.g_a) // 7 C.g_a = 42 fmt.Println(C.g_a) // 42 var n int32 n = int32(C.g_a) + 11 fmt.Println(n) // 53 }
值得注意的是,Go不认为C.int与int32或int是同一种类型,所以不能把C.int类型的变量直接赋值给int32类型的变量,如果要这么做,必须进行类型转换。
4.2 函数
用“C.函数名”来调用函数。
五、综合示例
六、练习
有疑问加站长微信联系(非本文作者)