go语言调用c语言动态库及交叉编译.pdfVIP

go语言调用c语言动态库及交叉编译.pdf

  1. 1、本文档共6页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 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)

166****9220 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档