cgo的个人总结
2017-03-30 21:13
337 查看
1.cgo的看法
go语言是一门比较新的语言,和C类语言的比较的亲和。前几年,其开源项目有点少,虽然go语言有很多优点,但是很多人都是抱着观望的态度去看待go。在没有很多开源项目的支持下,只能有cgo来接入原有羡慕中的一些模块(一般不会去用go语言重写,毕竟成本有点高)。
首先需要了解一些基本的go语言底层知识,就是go语言在进行syscall的时候会将goroutin所在的线程M上其他的G都移到其他的M上。然后进行C底层的系统调用。这样的话如果该syscall阻塞的话不会影响到其他的G。同样的,在使用CGO的时候也是会有类似的现象,在CGO返回前对应的G占用一个M。故可以把CGO中C函数看做在一个线程中执行。
CGO的用法
1、在使用CGO的时候C代码写的部分都要在注释里边,然后最后一行注释的下一行加上impourt “C”
2、C使用go语言中的变量。
go的标准类型转换为C的标准类型有
C.char
C.schar (signed char)
C.uchar (unsigned char)
C.int , C.uint (unsigned int)
C.long , C.ulong (unsigned long)
C.longlong (long long)
C.ulonglong (unsigned long long)
结构体,联合体等用C.struct_XXX(结构体名称)、C.union_XXX。
注意C.Cstirng 为char *类型,其底层是通过malloc申请的,注意要进行释放。
3、一般情况下C模块不可能都写在go语言文件中。首先,以注释的形式在看代码逻辑等方面会带来很大的不方便。所以在使用CGO的时候一般会将c提供个别接口,通过动态库链接的形式链接到go程序中。
main.go
ldd.h
ldd.c
将C模块编译为动态库:
gcc -shared -fPIC -o ldd.so ldd.c
go语言模块还是用go build正常编译
编译完以后可以用ldd查看可执行程序,可以看到依赖于//cgo LDFLAGE: -L (链接路径) -l动态库名 中对应的动态库。
个人总结:
由于CGO的调用会在独立的线程中执行,而且是用了线程独立栈,调用的时候也会有一定的性能牺牲。故建议write go in go way,尽量减少使用CGO。
ae5f
go语言是一门比较新的语言,和C类语言的比较的亲和。前几年,其开源项目有点少,虽然go语言有很多优点,但是很多人都是抱着观望的态度去看待go。在没有很多开源项目的支持下,只能有cgo来接入原有羡慕中的一些模块(一般不会去用go语言重写,毕竟成本有点高)。
首先需要了解一些基本的go语言底层知识,就是go语言在进行syscall的时候会将goroutin所在的线程M上其他的G都移到其他的M上。然后进行C底层的系统调用。这样的话如果该syscall阻塞的话不会影响到其他的G。同样的,在使用CGO的时候也是会有类似的现象,在CGO返回前对应的G占用一个M。故可以把CGO中C函数看做在一个线程中执行。
CGO的用法
1、在使用CGO的时候C代码写的部分都要在注释里边,然后最后一行注释的下一行加上impourt “C”
package main //#include <stdio.h> import "C" func main() { C.printf("hello world\n") return }
2、C使用go语言中的变量。
go的标准类型转换为C的标准类型有
C.char
C.schar (signed char)
C.uchar (unsigned char)
C.int , C.uint (unsigned int)
C.long , C.ulong (unsigned long)
C.longlong (long long)
C.ulonglong (unsigned long long)
结构体,联合体等用C.struct_XXX(结构体名称)、C.union_XXX。
注意C.Cstirng 为char *类型,其底层是通过malloc申请的,注意要进行释放。
package main //#include<stdio.h> //#include<stdlib.h> //struct man { // char *name; // int age; //} import "C" func main(){ iAge := 8 pstrName := C.Cstring("Go") C.printf("%s's age is: %d\n",pstrName,C.int(iAge)) var Golang C.struct_man = C.struct_man{pstrName, iAge} C.printf("%s's age is: %d\n",Golang.name,Golang.age) C.free(pstrName) }
3、一般情况下C模块不可能都写在go语言文件中。首先,以注释的形式在看代码逻辑等方面会带来很大的不方便。所以在使用CGO的时候一般会将c提供个别接口,通过动态库链接的形式链接到go程序中。
main.go
package main //cgo LDFLAGE: -L (链接路径) -l动态库名 //#include"ldd.h" func main() { C.SayHello() return }
ldd.h
#include<stdio.h> void SayHello();
ldd.c
void SayHello() { printf("hello\n"); }
将C模块编译为动态库:
gcc -shared -fPIC -o ldd.so ldd.c
go语言模块还是用go build正常编译
编译完以后可以用ldd查看可执行程序,可以看到依赖于//cgo LDFLAGE: -L (链接路径) -l动态库名 中对应的动态库。
个人总结:
由于CGO的调用会在独立的线程中执行,而且是用了线程独立栈,调用的时候也会有一定的性能牺牲。故建议write go in go way,尽量减少使用CGO。
ae5f
相关文章推荐
- PCA降维算法总结以及matlab实现PCA(个人的一点理解)
- 深度学习系列之YOLO 个人总结
- 个人工作总结03
- 个人项目总结 赵衍
- ZT C/C++变量命名规则,个人习惯总结
- 三分法问题个人总结&MS_活动中心问题
- 自习任我行 第二阶段每日个人总结1
- JAVA Sokcet(服务端)连接WebSocket个人总结
- 个人总结03
- 如何解决versions锁死的问题(mac)-个人总结
- JAVA DAO(Data Access Object)的个人总结
- 个人总结面试题
- 2013年个人总结
- 2011年"新秀杯"程序设计比赛——现场决赛参考解题报告和个人总结
- 团队项目个人工作总结(4月22日)
- 个人总结php笔试题五
- maven个人实战总结&FAQ
- 读写xml所有节点个人小结 和 读取xml节点的数据总结
- Keil的lib生成个人总结
- 个人项目-密码管理-总结一(Android访问AMP)