网上有很多讲解使用CGO实现Go中调用C代码的博客。总结起来,go中调用C一共有两种办法:
第一种是将C代码直接嵌入到GO源文件中
第二种是将C代码写在C文件中,再在GO文件中引入
go 语言调用C库
示例:
//foo.h
int count;
void foo();
//foo.c
#include <stdio.h>
#include "foo.h"
int count = 6;
void foo() {
printf("I am foo!\n");
}
//go program
package main
// #cgo LDFLAGS: -L ./ -lfoo
// #include <stdio.h>
// #include <stdlib.h>
// #include "foo.h"
import "C"
import "fmt“
func main() {
fmt.Println(C.count)
C.foo()
}
针对第二种调用方法,有以下3种解决方案。
方法1:go调用静态库
$> gcc -c foo.c
$> ar rv libfoo.a foo.o
$> go build foo.go
$> ./foo
注意:低版本可能不支持调用静态库,我测试go version go1.7.3 linux/amd64可以
方法2:go调用动态库
$> gcc -c foo.c
$> gcc -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o
$> go build foo.go
$> ./foo
注意:但在倒数第二步的编译过程中会出现如下“对foo未定义的引用“的错误:
解决方案:因为没有将共享库libfoo.so放在标准目录,所以要给装入器(loader)点帮助。有几个选择:可以用环境变量LD_LIBRARY_PATH,或者rpath。
方法3:在含有C函数声名和定义的go程序的当前文件目录下,直接执行命令:go build即可。
方法2:go调用动态库
$> gcc -c foo.c
$> gcc -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o
$> go build foo.go
$> ./foo
注意:但在倒数第二步的编译过程中会出现如下“对foo未定义的引用“的错误:
解决方案:因为没有将共享库libfoo.so放在标准目录,所以要给装入器(loader)点帮助。有几个选择:可以用环境变量LD_LIBRARY_PATH,或者rpath。
方法3:在含有C函数声名和定义的go程序的当前文件目录下,直接执行命令:go build即可。