- 1、本文档共6页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
go语⾔调⽤c语⾔动态库及交叉编译
实现基础:CGO编程
C/C++经过⼏⼗年的发展,已经积累了庞⼤的软件资产,它们很多久经考验⽽且性能已经⾜够优化。Go语⾔必须能够站在C/C++这个巨⼈
的肩膀之上,有了海量的C/C++软件资产兜底之后,我们才可以放⼼愉快地⽤Go语⾔编程。C语⾔作为⼀个通⽤语⾔,很多库会选择提供
⼀个C兼容的API,然后⽤其他不同的编程语⾔实现。Go语⾔通过⾃带的⼀个叫CGO 的⼯具来⽀持C语⾔函数调⽤,同时我们可以⽤Go语
⾔导出C动态库接⼝给其它语⾔使⽤。
如果有纯Go的解决⽅法就不要使⽤CGO;CGO中涉及的C和C++构建问题⾮常繁琐;CGO有⼀定的限制⽆法实现解决全部的问题;不要试
图越过CGO的⼀些限制。⽽且CGO只是⼀种官⽅提供并推荐的Go语⾔和C/C++交互的⽅法。如果是使⽤的gccgo的版本,可以通过
gccgo的⽅式实现Go和C/C++的交互。同时SWIG也是⼀种选择,并对C诸多特性提供了⽀持。
要使⽤CGO特性,需要安装C/C++构建⼯具链,在macOS和Linux下是要安装GCC ,在windows下是需要安装MinGW ⼯具。同时需要保
证环境变量 CGO_ENABLED 被设置为1,这表⽰CGO是被启⽤的状态。在本地构建时CGO_ENABLED默认是启⽤的,当交叉构建时CGO默
认是禁⽌的。⽐如要交叉构建ARM环境运⾏的Go程序,需要⼿⼯设置好C/C++交叉构建的⼯具链,同时开启CGO_ENABLED环境变量。
本⽂参考:
基础概念
import C 语句
如果在Go代码中出现了 import C 语句则表⽰使⽤了CGO特性,紧跟在这⾏语句前⾯的注释是⼀种特殊语法,⾥⾯包含的是正常的C语⾔代
码。当确保CGO启⽤的情况下,还可以在当前⽬录中包含C/C++对应的源⽂件。
举个最简单的例⼦ :
package main
/*
#include stdio.h
void printint(int v) {
printf(printint: %d\n, v);
}
*/
import C
import unsafe
func main() {
v := 42
C.printint(C.int(v))
}
这个例⼦展⽰了cgo的基本使⽤⽅法。开头的注释中写了要调⽤的C函数和相关的头⽂件,头⽂件被include之后⾥⾯的所有的C语⾔元素都
会被加⼊到”C”这个虚拟的包中。需要注意的是,import C导⼊语句需要单独⼀⾏,不能与其他包⼀同import。向C函数传递参数也很
简单,就直接转化成对应C语⾔类型传递就可以。如上例中C.int(v)⽤于将⼀个Go中的int类型值强制类型转换转化为C语⾔中的int类型值,
然后调⽤C语⾔定义的printint函数进⾏打印。
需要注意的是,Go是强类型语⾔,所以cgo中传递的参数类型必须与声明的类型完全⼀致,⽽且传递前必须⽤”C”中的转化函数转换成对
应的C类型,不能直接传⼊Go中类型的变量。
#cgo 语句
在 import C 语句前的注释中可以通过#cgo 语句设置编译阶段和链接阶段的相关参数。编译阶段的参数主要⽤于定义相关宏和指定头⽂件检
索路径。链接阶段的参数主要是指定库⽂件检索路径和要链接的库⽂件。
// #cgo CFLAGS: -DPNG_DEBUG=1 -I./include
// #cgo LDFLAGS: -L/usr/local/lib -lpng
// #include png.h
import C
上⾯的代码中, CFLAGS 部分, -D 部分定义了宏PNG_DEBUG,值为1; -I 定义了头⽂件包含的检索⽬录。 LDFLAGS 部分, -L 指定了链接
时库⽂件检索⽬录, -l 指定了链接时需要链接png库。
因为C/C++遗留的问题,C头⽂件检索⽬录可以是相对⽬录,但是库⽂件检索⽬录则需要绝对路径。在库⽂件的检索⽬录中可以通过
${SRCDIR}变量表⽰当前包⽬录的绝对路径:
// #cgo LDFLAGS: -L${SRCDIR}/libs -lfoo
上⾯的代码在链接时将被展开为:
// #cgo LDFLAGS: -L/go/src/foo/libs -lfoo
项⽬⽰例
需求
Go项⽬中需要调⽤C语⾔动态库 libcoreserver.so 中的 GetServerIP ⽅法获取服务器IP地址。
头⽂件
头⽂件 CoreServer.h 内容如下:
#ifndef CoreServer__h
#define Co
文档评论(0)