golang 相互引用_Golang与C互用以及调用C的so动态库和a静态库
Golang与C的关系非常密切,下面主要介绍在Golang中使用C。
一. Golang中嵌入C代码
1 package main
2
3 //#include
4 //#include
5 /* 6 void Hello(char *str) { 7 printf("%s\n",str); 8 } 9 */
10 import "C" //假设把C当成包,其实有点类似C++的名字空间
11 import "unsafe" //C指针的使用,在C代码中申请的空间,GC垃圾回收机制不会管理,所以需要自己手动free申请的空间
12
13 func main() {
14 s := "Hello Cgo"
15 cs := C.CString(s)
16 C.Hello(cs)
17 C.free(unsafe.Pointer(cs))
18 }
3,4行的注释也可以写/* */形式
第4行与第5行之间不能有空行,同样第9行与第10行之间也不
能有行,否则编译时cgo会报错:
jack@jack-VirtualBox:~/mygo/src/myC/tmp$go run goc.go
# command-line-arguments
could not determine kind of name for C.Hello
could not determine kind of name for C.free
Golang中调用C的动态库so
C库源程序代码:
1 //foo.c
2 #include
3
4 int Num = 8;
5
6 void foo(){
7 printf("I dont have new line.");
8 printf("I have new line\n");
9 printf("I have return\r");
10 printf("I have return and new line\r\n");
11 }
1 //foo.h
2 #ifndef __FOO_H
3 #define __FOO_H
4
5 #ifdef __cplusplus
6 extern "C" {
7 #endif
8
9 extern int Num;
10 extern void foo();
11
12 #ifdef __cplusplus
13 }
14 #endif
15
16 #endif
Go调用C库的代码:
1 package main
2
3 /* 4 #cgo CFLAGS: -I. 5 #cgo LDFLAGS: -L. -lfoo 6 #include 7 #include 8 #include "foo.h" 9 */
10 import "C"
11 import "unsafe"
12 import "fmt"
13
14 func Prin(s string) {
15 cs := C.CString(s)
16 defer C.free(unsafe.Pointer(cs))
17 C.fputs(cs,(*C.FILE)(C.stdout))
18 //C.free(unsafe.Pointer(cs))
19 C.fflush((*C.FILE)(C.stdout))
20 }
21
22 func main() {
23 fmt.Println("vim-go")
24 fmt.Printf("rannum:%x\n",C.random())
25 Prin("Hello CC")
26 fmt.Println(C.Num)
27 C.foo()
28 }
注意import “C”这行与第9行之间也不能有空格,原因同上编译会报错。
go与库、头文件的目录结构,以及编译:
jack@jack-VirtualBox:~/mygo/src/myC/sotest$go build cc.go //编译之后产生cc
jack@jack-VirtualBox:~/mygo/src/myC/sotest$ ls
cc cc.go foo.h libfoo.so
jack@jack-VirtualBox:~/mygo/src/myC/sotest$ export LD_LIBRARY_PATH=./
jack@jack-VirtualBox:~/mygo/src/myC/sotest$ ./cc
vim-go
rannum:6b8b4567
Hello CC8
I dont have new line.I have new line
I have return and new line
如果c库的程序改为下面这样:
1 //foo.c
2 #include
3
4 int Num = 8;
5
6 void foo(){
7 printf("I dont have new line.");
8 //printf("I have new line\n");
9 //printf("I have return\r");
10 //printf("I have return and new line\r\n");
11 }
此时,go中调用foo时没有任何反应,即不会输出,不会输出的原因是printf后面没有加换行符,但是如果加了8,9,10这些测试行后,第7行也会显示,原因是第10行最后有一个换行符,这个应该是向stdout输出时,字符流是放在buffer中,如果没有换行,buffer中的数据不会立即输出。在go调用C的测试程序中有写了一个测试小函数用来测试stdout,验证了没有fflush,stdout上不会显示输出信息。但平时在写C程序的时候,似乎没有这样的问题,这个是因为C的运行环境自动做了fflush的动作,这个可能是Golang的不足,也许golan表g认为这样做更好。这只是个人的分析,如有分析不对的地方,请跟贴,谢谢。
Golang调用C的静态库a
所有源程序与动库演示代码类似,只是编译C库时,是用的静态编译,如下所示:
jack@jack-VirtualBox:~/mygo/src/myC$ls
foo.c
jack@jack-VirtualBox:~/mygo/src/myC$gcc -c foo.c
foo.c foo.o
jack@jack-VirtualBox:~/mygo/src/myC$ar -rv libfoo.a foo.o
foo.c foo.o libfoo.a
Go调用的代码与动态库一样,下面是目录结构:
jack@jack-VirtualBox:~/mygo/src/myC/atest$ls
cc cc.go foo.h libfoo.a
总结
如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您喜欢交流学习经验,点击链接加入交流1群:1065694478(已满)交流2群:163560250
golang 相互引用_Golang与C互用以及调用C的so动态库和a静态库相关推荐
- golang 相互引用_golang go run undefined 同一个package中函数互相调用的问题
golang中同一个package中函数互相调用的问题 同一个packge中(test) a.go package main func main(){ Test() } b.go package ma ...
- go语言调用c 的头文件 so,Golang生成共享库(shared library)以及Golang生成C可调用的动态库.so和静态库.a...
Golang类似于C的静态语言,效率也接近于C,如果Golang也可以导出可供C调用的库,那可以和很多高级语言say goodbye了,goodbye似乎又有点武断,但至少说,Golang可以做很多事 ...
- golang 相互引用_Go 不同文件之间的引用
同一个包里面,不同文件之间,不需要 import,直接用就好.不同包的话,需要引用包,只能使用大写字母开头的方法 ,变量 等等,小写子母开头的只能包内使用. 简单来说 :大写字母开头的变量,方法暴露给 ...
- ios 重复引用 静态库_iOS-如果静态库(.a)包含重复的目标文件(.o),会发生什么?
AFAIK,较旧版本的Xcode如果链接了多次,则无法链接静态库.我认为存在一种重复的目标文件或符号问题. 最近,我意识到Xcode5不再在静态库的重复链接上报告相关错误.这是我的测试. >我写 ...
- Golang生成C动态库.so和静态库.a
Go 生成C动态库.so和静态库.a 源代码 package mainimport "C" import "fmt"//export hello func he ...
- ios 重复引用 静态库_Swift 制作静态库
Github地址:https://github.com/LINGLemon/LXFSwiftApp Swift不支持.a的静态库,因此只能制作.framework的静态库 动态库和静态库的区别 库: ...
- QT中引用动态库(.so) 和 静态库 (.a)
1 增加动态库 pro文件中LIBS一行中添加 如新增libvlc.so LIBS += -L/usr/local/lib -lvlc 其中/usr/local/lib为libvlc.so所处的绝对路 ...
- iOS架构-制作静态库.a和.framework 的相互依赖(10)
有一句名言:当你知道的东西越多,你才会发现你不懂的东西越多. 现在我有点体会到了,当我去了解静态库,我发现我要学习脚本:当我接触编译C/C++库,我发现我要去了解交叉编译:当我想了解组件化架构,我发现 ...
- Linux下静态库与动态库的引用关系深入分析
很久就想写一篇关于动态库和静态库互相引用的一篇文章,但是总感觉准备不充分,而一直没有勇气下笔,最近在和同事的讨论中,似乎有了一些新的认识,想把这些记录下来,和大家进行一次分享,同时也是做一次记录. 这 ...
最新文章
- WMI技术介绍和应用——查询环境变量
- CSS3动画属性之Transition
- Mac的文件比对工具:Meld、Beyond Compare
- 手写弹出框,设置遮罩,布局设计。
- 1-1docker加速器
- Java笔记-对称加密AES的使用
- 6park留园 android,App Store 上的“掌上留园-6park”
- 万能电子狗升级工具_HUD抬头显示,车萝卜再推新品,屏幕全新升级
- 事件对象使用方法大全(源码解析)
- 48小时备考TOGAF经验分享
- mac地址查 计算机名字,怎么看mac地址-教你通过MAC地址查询设备的厂商名称
- C语言中有关字符串的库函数(3)
- xlsx to vcf
- C# 命名空间中不存在类型或命名空间名,是否缺少程序集引用
- Oracle的软解析(soft prase)和硬解析(hard prase)及绑定变量
- 腾讯邮箱比阿里邮箱好,腾讯邮箱还是阿里邮箱?
- ORA-03113和ORA-00204问题处理
- MySQL中DATE_FORMAT()函数的说明和简介
- 传感器的低频响应和截止频率
- win10系统无法加载操作系统且自动恢复失败的解决方案
热门文章
- 云计算实战系列二(Linux-用户管理)
- 计算机网络---HTTP状态码
- java如何实现tcp传输图像_如何在java中实现TCP服务器和TCP客户端传输文件
- 【2019.09.21】ICPC Latin American Regional-2017
- java实现文件上传(使用FromData)
- 解决postman环境切换,自动获取api签名时间及签名
- Python(set/list/dict/tuple)
- [转载]值得推荐的C/C++框架和库
- POJ 3107 - Godfather
- Android学习笔记17:单项选择RadioButton和多项选择CheckBox的使用