您的位置:首页 > 编程语言 > Go语言

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”

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: