Go与C的互相调用
官方参考:https://github.com/golang/go/wiki/cgo#function-pointer-callbacks
Go调用C代码
调用C的lib
c、go代码文件如下
1 2 3 4
| . ├── c_module.c ├── c_module.h └── main.go
|
c_module.h
1
| extern int add(int a, int b);
|
c_module.c
1 2 3 4
| #include "c_module.h" int add(int a, int b) { return a+b; }
|
编译为.so
1
| gcc -shared -o libc_module.so c_module.c
|
记得在生成.so文件的名称前面加一个lib
main.go
1 2 3 4 5 6 7 8 9 10
| package main
import "C" import "fmt" func main() { fmt.Println(C.add(10, 5)) }
|
编译go代码
1
| go build -o main main.go
|
运行
1
| export LD_LIBRARY_PATH=./ && ./main
|
输出
调用成功
C代码调用Go代码
调用go的lib
Go语言写的代码可以编译为动态库或静态库,之后C语言链接该动态库或静态库就可以调用Go语言写的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package main; import "C"
func main() {}
func Hello() string { return "Hello" }
func Print_a() { println("aaaaa") }
|
上面的//export 是一个特殊的注释,代表着导出该函数。
编译
1
| go build -buildmode=c-shared -o libgo.so main.go
|
编译完后,会出现libgo.h 和libgo.so两个文件
如果是想静态编译的话
1
| go build -buildmode=c-archive -o libgo.a main.go
|
编译完后,会出现libgo.h 和libgo.a两个文件
这里写一个main.c来调用go
main.c
1 2 3 4 5 6 7 8 9 10
| #include <stdio.h> #include "libgo.h"
void main() { GoString str; str = Hello(); Print_a(); printf("%d\n",(int)str.n); }
|
静态库编译
1
| gcc main.c libgo.a -lpthread -o main
|
运行
成功的打印了aaaaa以及字符串的长度。
动态库编译
1 2
| export LD_LIBRARY_PATH=./ gcc main.c -L./ -lgo -lpthread -o main
|
查看链接情况
1 2 3 4 5 6
| ldd main linux-vdso.so.1 (0x00007ffc22882000) libgo.so => ./libgo.so (0x00007ff893c0f000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff893a13000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff8939f0000) /lib64/ld-linux-x86-64.so.2 (0x00007ff893d63000)
|
正常的,运行