cgo 提供了 golang 和 C 语言相互调用的机制
cgo使用需要安装gcc
1
2
3
4
5
6
|
> gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin17.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
|
通过import "C"
语句启用cgo特性
示例
可以用注释符//和/**/包围C代码,
import "C"
和包含C代码之间没有空行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// +build go1.10
package main
//void SayHello(_GoString_ s);
import "C"
import (
"fmt"
)
func main() {
C.SayHello("Hello, World\n")
}
//export SayHello
func SayHello(s string) {
fmt.Print(s)
}
|
使用cgo声明一个函数void SayHello
,在go程序内实现这个函数,使用export
关键字输出符号为SayHello
供c程序调用
运行输出:
1
2
|
> go run sayhello.go
Hello, World
|
引入c语言标准库,在go程序中调用c实现的函数
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
package main
/*
#include <stdio.h>
#include <errno.h>
static void SayHello(const char* s) {
puts(s);
}
void printint(int v) {
printf("printint: %d\n", v);
}
static int add(int a, int b) {
return a + b;
}
static int div(int a, int b) {
if (b == 0) {
errno = EINVAL;
return 0;
}
return a/b;
}
*/
import "C"
import (
"fmt"
"os"
)
func main() {
C.SayHello(C.CString("Hello, World\n"))
C.printint(C.int(10))
fmt.Println(os.Getenv("CGO_ENABLED"))
fmt.Println(os.Getenv("GOPATH"))
fmt.Println(C.add(6, 4))
v1, err1 := C.div(6, 2)
fmt.Println(v1, err1)
v2, err2 := C.div(6, 0)
fmt.Println(v2, err2)
}
|
运行输出:
1
2
3
4
5
6
7
8
9
|
> go run hello.go
Hello, World
printint: 10
/Users/piao/data/golang
10
3 <nil>
0 invalid argument
|
运行go tool cgo hello.go
命令,可生成了一个包含c目标文件的文件夹_obj
引入c语言标准库,在go程序中调用c标准库函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package main
/*
#include <stdlib.h>
*/
import "C"
import (
"fmt"
"time"
)
func main() {
C.srandom(C.uint(time.Now().UTC().UnixNano()))
for i := 0; i < 10; i++ {
fmt.Printf("%d\n", int(C.random()))
}
}
|
运行输出:
1
2
3
4
5
6
7
8
9
10
11
|
> go run main.go
1127749496
1069904962
1041856883
569707171
457553066
1182433128
1819607608
295108270
1821523696
1298408739
|
独立c语言文件
1
2
3
4
5
|
#include <stdio.h>
void SayHi(const char* s) {
puts(s);
}
|
1
2
3
4
5
6
7
8
|
package main
//void SayHi(const char* s);
import "C"
func main() {
C.SayHi(C.CString("Hello, cgo"))
}
|
使用go run .
或 go build .
命令编译
参考