CGO,GOLANG调用C库,调用代码、静态库或动态库
CGOCGO可以让golang和c互相调用,譬如x264或者aac编解码,用go再实现一遍比较麻烦,直接调用c的函数会更合适。 写了一个fdkaac的binding:https://github.com/winlinvip/go-fdkaac 参考这两篇文章,讲得很清楚: 有个例子,go调用x264的函数:https://github.com/winlinvip/codec 在import “C”之前加preamble(注释),包含头文件。这样在C这个命名空间中就可以用C的函数了。 下面是个C++导出的库: // winlin.h
#ifdef __cplusplus
extern "C"{
#endif
// get the version.
extern int winlin_version();
#ifdef __cplusplus
}
#endif
// winlin.cpp
// g++ -c -o winlin.o winlin.cpp && ar -rs winlin.a winlin.o
#include "winlin.h"
int winlin_version() {
return 0x01020304;
}
// main.cpp
// g++ -o cpp main.cpp winlin.a
#include <stdio.h>
#include "winlin.h"
int main(int argc,char** argv) {
printf("version is %#xn",winlin_version());
return 0;
}
下面是main.cpp在Centos6的执行结果: [winlin@centos6 gos]$ ./cpp
version is 0x1020304
[winlin@centos6 gos]$ ldd cpp
linux-vdso.so.1 => (0x00007fff9f674000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003cbda00000)
libm.so.6 => /lib64/libm.so.6 (0x0000003cb0a00000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003cbca00000)
libc.so.6 => /lib64/libc.so.6 (0x0000003cb0e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003cb0600000)
cgo,可以在golang中用这个静态库: // go run main.go
package main
// #include "winlin.h"
// #cgo LDFLAGS: ${SRCDIR}/winlin.a -lstdc++
import "C"
import "fmt"
func main() {
fmt.Println("version is",C.winlin_version())
}
总之,cgo的编译和一般的c或c++差别不大,引入的库和头文件之类。 [winlin@centos6 gos]$ go build -o test main.go
[winlin@centos6 gos]$ ldd test
linux-vdso.so.1 => (0x00007fff8df9f000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003cbda00000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003cb1600000)
libc.so.6 => /lib64/libc.so.6 (0x0000003cb0e00000)
libm.so.6 => /lib64/libm.so.6 (0x0000003cb0a00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003cb0600000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003cbca00000)
[winlin@centos6 gos]$ ./test
version is 16909060
在Centos6下面的golang程序,没有用cgo: [winlin@centos6 srs-plus]$ ldd objs/bocar
linux-vdso.so.1 => (0x00007fffb1fff000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003cb1600000)
libc.so.6 => /lib64/libc.so.6 (0x0000003cb0e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003cb0600000)
下面是用了cgo的golang程序: [winlin@centos6 gos]$ ldd test
linux-vdso.so.1 => (0x00007ffff43ff000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003cb1600000)
libc.so.6 => /lib64/libc.so.6 (0x0000003cb0e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003cb0600000)
下面是C++程序: [winlin@centos6 srs-plus]$ ldd objs/srs
linux-vdso.so.1 => (0x00007fff5d9ff000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003cb1200000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003cbda00000)
libm.so.6 => /lib64/libm.so.6 (0x0000003cb0a00000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003cbca00000)
libc.so.6 => /lib64/libc.so.6 (0x0000003cb0e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003cb0600000)
都只是引用了系统的so,譬如c和c++,pthread还有ldl之类的。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |