cgo
dev
#go
2018/02/27
cgo 相关
热身
基于C标准库
1
2
3
4
5
6
7
8
9
// demo. go
package main
// #include <stdio.h>
import "C"
func main() {
C. puts(C. CString("Hello, World \n " ))
}
import "C"
启用CGO,并包含<stdio.h>
CGO包的
C.CString将Go字符串转C字符串
调C的
C.puts 输出转换后的C字符串
使用自己的C函数
1. 直接在 go 源码中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main
/*
#include <stdio.h>
void SayHello(const char* s) {
puts(s);
}
*/
import "C"
func main() {
C. SayHello(C. CString("Hello, World \n " ))
}
2. 拆分到 c
1
2
3
4
5
6
// hello. c
#include <stdio.h>
void SayHello(const char* s) {
puts(s);
}
1
2
3
4
5
6
7
8
package main
// void SayHello(const char* s);
import "C"
func main() {
C. SayHello(C. CString("Hello, World \n " ))
}
cgo作用
Go 调 C 函数
导出Go函数,可以生成 生成静态或动态库,给C用
编译过程
预处理:将代码中的引用进行代码替换 main.c -> main.i
编译:main.i > 汇编 main.s
汇编:main.s > 可重定位的目标文件 main.o
链接:main.o 和其他依赖模块组合成可执行文件
编译器编译动态链接 .so 时,用延迟绑定
延迟绑定两个关键数据结构:全局偏移量表(Global Offset Table, GOT)和过程链接表(Procedure Linkage Table, PLT)
c
1
2
3
4
// dd.h
int Foo(int a,int b);
int Bar();
dd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// dd.c
#include "dd.h"
#include <stdio.h>
int Foo (int a,int b) {
return a+ b;
}
int Bar () {
printf ("hello, I am dd" );
return 42
}
main.c
1
2
3
4
5
6
7
8
9
// main.c
#include "dd.h"
#include "stdio.h"
int main() {
printf("1+2=%d\n",Foo(1,2));
Bar();
return 0;
}
静态
1
gcc main.c dd.c -o main.exe
动态库
1
2
gcc -shared -fpic -o dd.dll dd.c
gcc main.c -o main2.exe dd.dll
go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// dd. go
package main
import "C"
import (
"fmt"
)
// export Foo
func Foo(a, b int ) int {
return a + b
}
// export Bar
func Bar() {
fmt. Println("I am bar, not foo!" )
}
func main() {}
动态库
1
2
go build -o ddgo.dll -buildmode=c-shared dd.go
gcc main.c -o main2.exe ddgo.dll
静态库
1
2
go build -o ddgo.a -buildmode=c-archive dd.go
gcc main.c -o main4.exe ddgo.a -l winmm -l ntdll -l Ws2_32
Go 的八种 Build Mode
exe
(静态编译)
exe
(动态链接 libc
)
exe
(动态链接 libc
和非 Go 代码)
pie
地址无关可执行文件(安全特性)
c-archive
C 的静态链接库
c-shared
C 的动态链接库
shared
Go 的动态链接库
plugin
Go 的插件
link
动态库显式调用
https://www.cnblogs.com/Anker/p/3746802.html
http://www.cnblogs.com/mydomain/archive/2012/10/06/2712833.html
asm
为什么spring boot 倾向 fat jar