go语言调用c 的头文件 so,Golang生成共享库(shared library)以及Golang生成C可调用的动态库.so和静态库.a...

Golang类似于C的静态语言,效率也接近于C,如果Golang也可以导出可供C调用的库,那可以和很多高级语言say goodbye了,goodbye似乎又有点武断,但至少说,Golang可以做很多事,而且效率优于很多高级语言,这样说应该没有问题。

接下来,就从三个方面分别来介绍Golang中关于库的使用。

Using Share Library

The latest Go 1.5 version is out. As part of the new features, Go compiler can compile packages as a shared libraries.

It accepts -buildmode argument that determines how a package is compiled. These are the following options:

* archive: Build the listed non-main packages into .a files. Packages named main are ignored.

* c-archive: Build the listed main package, plus all packages it imports, into a C archive file.

* c-shared: Build the listed main packages, plus all packages that they import, into C shared libraries.

* shared: Combine all the listed non-main packages into a single shared library.

* exe: Build the listed main packages and everything they import into executables. Packages not named main are ignored.

By default, listed main packages are built into executables and listed non-main packages are built into .a files.

平时编译、运行golang,可能用得比较多的是下面这些:

go run xxx.go //直接运行xxx.go,有点类似解释语言,比如lua, python,其实执行go run,是对源文件做了build,然后再run执行文件的,只是这些都在后台做了

go build xxx.go //编译产生同名的执行档,如果在源文件目录下直接go build会产生与目录名同名的可执行档

go install xxx.go //也是编译,只是编译后会将同名的执行档安装到$GOPATH/bin下面,同样在源文件目录下直接go install,会把与目录同名的可执行档安装在$GOPATH/bin下

以上的go build都是默认的编译,也就是-buildmode是default的

By default, listed main packages are built into executables and listed non-main packages are built into .a files.

现在进入正题,这里我主要是要说明下面这个选项的使用方法:

* shared: Combine all the listed non-main packages into a single shared library.

我们先看一个hello world的例子:

package main

import "fmt"

int main(){

fmt.Println("hello world")

}

这里的fmt就是一个share library,这是go里面自带的,现在如果想自定义一个共享库,应该怎么做?

假设在$GOPATH/src下有:

--myAdd --add.go--myCall --main.go

详细目录如下:

jack@jack-VirtualBox:~/mygo/src$echo $GOPATH

/home/jack/mygo

jack@jack-VirtualBox:~/mygo$ls

bin pkg src

jack@jack-VirtualBox:~/mygo/src$ls myAdd

add.go

jack@jack-VirtualBox:~/mygo/src$ls myCall

main.go

现在我们要自定义一个myAdd的package,像fmt一样的使用,先看下myAdd/add.go的内容:

1 package myAdd

2

3 func Sum(x, y int) int {

4 return x + y

5 }

在编译自定义package前,先看下官方怎么说:

Before compile any shared library, the standard builtin packages should be installed as shared library. This will allow any other shared library to link with them.

意思是在编译任何共享包前,先要把官方自身的标准包先以共享包方式安装下,这样其他的包就可以与它们做link。

下面就按官方要求先来编译一下:

jack@jack-VirtualBox:~/mygo/src/myAdd$go install -buildmode=shared -linkshared std

编译后会在GOROOT的pkg目录下安装标准共享库, 这里对应linux_386_dynlink这个目录:

jack@jack-VirtualBox:~/mygo/src/golib$ ll ~/go/pkg

total 28

drwxr-xr-x 7 jack jack 4096 12月 5 09:21 ./

drwxr-xr-x 11 jack jack 4096 5月 25 2017 ../

drwxr-xr-x 2 jack jack 4096 5月 25 2017 include/

drwxr-xr-x 30 jack jack 4096 5月 25 2017 linux_386/

drwxrwxr-x 29 jack jack 4096 12月 5 09:22 linux_386_dynlink/

drwxr-xr-x 3 jack jack 4096 5月 25 2017 obj/

drwxr-xr-x 3 jack jack 4096 5月 25 2017 tool/

jack@jack-VirtualBox:~/mygo/src/golib$ ll ~/go/pkg/linux_386_dynlink/

total 31252

drwxrwxr-x 29 jack jack 4096 12月 5 09:22 ./

drwxr-xr-x 7 jack jack 4096 12月 5 09:21 ../

drwxrwxr-x 2 jack jack 4096 12月 5 09:22 archive/

-rw-rw-r-- 1 jack jack 121966 12月 5 09:21 bufio.a

-rw-rw-r-- 1 jack jack 10 12月 5 09:22 bufio.shlibname

-rw-rw-r-- 1 jack jack 111466 12月 5 09:21 bytes.a

-rw-rw-r-- 1 jack jack 10 12月 5 09:22 bytes.shlibname

drwxrwxr-x 2 jack jack 4096 12月 5 09:22 compress/

drwxrwxr-x 2 jack jack 4096 12月 5 09:22 container/

-rw-rw-r-- 1 jack jack 94220 12月 5 09:21 context.a

-rw-rw-r-- 1 jack jack 10 12月 5 09:22 context.shlibname

drwxrwxr-x 4 jack jack 4096 12月 5 09:22 crypto/

-rw-rw-r-- 1 jack jack 20014 12月 5 09:21 crypto.a

-rw-rw-r-- 1 jack jack 10 12月 5 09:22 crypto.shlibname

drwxrwxr-x 3 jack jack 4096 12月 5 09:22 database/

drwxrwxr-x 2 jack jack 4096 12月 5 09:22 debug/

drwxrwxr-x 2 jack jack 4096 12月 5 09:22 encoding/

-rw-rw-r-- 1 jack jack 5494 12月 5 09:21 encoding.a

-rw-rw-r-- 1 jack jack 10 12月 5 09:22 encoding.shlibname

-rw-rw-r-- 1 jack jack 3846 12月 5 09:21 errors.a

-rw-rw-r-- 1 jack jack 10 12月 5 09:22 errors.shlibname

-rw-rw-r-- 1 jack jack 84486 12月 5 09:21 expvar.a

-rw-rw-r-- 1 jack jack 10 12月 5 09:22 expvar.shlibname

-rw-rw-r-- 1 jack jack 155402 12月 5 09:21 flag.a

-rw-rw-r-- 1 jack jack 10 12月 5 09:22 flag.shlibname

//GOROOT如下:

jack@jack-VirtualBox:~/samba_share/golang$echo $GOROOT

/home/jack/go

接下来,就可以编译自定义的共享库,并link到标准std库:

jack@jack-VirtualBox:~/mygo/src$go install -buildmode=shared -linkshared myAdd

jack@jack-VirtualBox:~/mygo/src$ls

github.com golang.org myAdd test

jack@jack-VirtualBox:~/mygo/src$ls myAdd/

add.go //这里并没有产生仍何文档,产生在那里接着向下看

实际产生共享是在GOPATH/pkg目录下:

jack@jack-VirtualBox:~/mygo$ls

bin pkg src

jack@jack-VirtualBox:~/mygo$ls pkg

linux_386 linux_386_dynlink

jack@jack-VirtualBox:~/mygo$ls pkg/linux_386_dynlink/

libmyAdd.so myAdd.a myAdd.shlibname //这些库在编译时已经链接到标准std库,所以下面在应用程序中可以直接使用。

下面是应用程序的代码:

jack@jack-VirtualBox:~/mygo/src$ vim myCall/main.go

1 package main

2

3 import (

4 "fmt"

5 "myAdd" //这就是上面自定义package,如果这里不import,只要下面用了包里面的函数,gofmt也会自动把这个包加进来,是不是有点跟使用fmt等其他包一样的用法

6 )

7

8 func main() {

9 fmt.Println("my Call application")

10 fmt.Printf("Sum: %d\n", myAdd.Sum(2, 3))

11 }

jack@jack-VirtualBox:~/mygo/src$ ./main

my Call application

Sum: 5

Golang生成C可调用的动态库so

假设代码结构如下:

jack@jack-VirtualBox:~/mygo/src/mylib$ ls

exptest.go

jack@jack-VirtualBox:~/mygo/src/mylib$ vim exptest.go

1 package main

2

3 import "C"

4 import "fmt"

5

6 //export Summ

7 func Summ(x, y int) int {

8 return x + y

9 }

10

11 //export Hello

12 func Hello(str string) {

13 fmt.Printf("Hello: %s\n", str)

14 }

15

16 func main() {

17 // We need the main function to make possible

18 // CGO compiler to compile the package as C shared library

19}

官方说法:

Go functions can be executed from C applications. They should be exported by using the following comment line://export

//export your_function_name目的是产生对应的头文件函数声明,以及cgo的与C之间一些转换规则,详细可以参考生成的头文件。

另外,import “C”这个也是不能少的,表示导入一个C库

下面就是编译共享库:

//The packaged should be compiled with buildmode flags c-shared or c-archive:

jack@jack-VirtualBox:~/mygo/src/mylib$ go build -buildmode=c-shared -o libexptest.so exptest.go

jack@jack-VirtualBox:~/mygo/src/mylib$ ls

exptest.go libexptest.h libexptest.so

下面写一个C程序调用这个so动态库:

jack@jack-VirtualBox:~/mygo/src/mylib$vim exptest.c

1 #include

2 #include "libexptest.h" //上面产生的头文件

3

4 int main() {

5 printf("This is exptest application.\n");

6 GoString str = {"Hi JXES", 7};

7 Hello(str); //调用的函数

8 printf("sum: %d\n", Summ(2, 3)); //调用的函数

9 return 0;

10 }

jack@jack-VirtualBox:~/mygo/src/mylib$export LD_LIBRARY_PATH=./

jack@jack-VirtualBox:~/mygo/src/mylib$echo $LD_LIBRARY_PATH

./

jack@jack-VirtualBox:~/mygo/src/mylib$./exptest

This is exptest application.

Hello: Hi JXES

sum: 5

这里需要说明下,在linux系统中应用程序关联到共享库时,都是从LD_LIBRARY_PATH环境变量指定的目录下找需要的.so,所以这里一定要指定在当前目录,如果不指定,可以把产生的so文件复制到/usr/lib下也可以。

Golang调用静态库.a

产生静态库只是编译的时候产生.a的静态库,库与测试程序代码如上,编译方法是:

jack@jack-VirtualBox:~/mygo/src/mylib$ go build -buildmode=c-archive -o libexptest.so exptest.go

jack@jack-VirtualBox:~/mygo/src/mylib$ ls

exptest.go libexptest.h libexptest.a

````

应用程序编译的方法如下:

$ gcc -o exptest exptest.c libexptest.a “`

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/385781.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从青铜到王者的路线,java不同系统间数据同步

深耕技术,啃下22个技术点 互联网行业更新换代非常快,行业常态便是不断学习,因此这些主流技术你一个都不能落下! ①并发编程 Java并发编程是整个Java开发体系中最难以理解,但也是最重要的知识点之一,因此学习…

c语言 大雨 班上多个同学准备,2015年计算机二级考试《C语言》提高练习题(7)

1[单选题] 若有C语言表达式23*47/3,以下选项中叙述正确的执行顺序是A.先执行3*4得12,再执行212得14,再执行7/3得2,最后执行142得16B.先执行3*4得12,再执行7/3得2.5,最后执行2122.5得16.5C.先执行7/3得2&…

从青铜到王者的路线,java枚举类使用场景

一、先来解读:23种设计模式要点 1.单例模式(Singleton Pattern) 2.工厂模式 3.抽象工厂模式(Abstract Factory Pattern) 4.模板方法模式(Template Method Pattern) 5.建造者模式(Bu…

android tag的作用,Android中的Context的作用(2)

ContextImpl关键成员和函数/*** Common implementation of Context API, which provides the base* context object for Activity and other application components.*/classContextImplextendsContext {privatefinalstaticString TAG "ContextImpl";privatefinalsta…

企业级项目实战讲解!javamap排序规则

一、服务发布简介 分布式系统架构下,服务发布是一件很麻烦的事情,特别是在构建自动发布流程和灰度测试的策略两个核心方面。通常情况下如果不涉及数据层面的灰度流程,服务可以灰度上线,或者滚动上线,这两种方式很常用…

android页面设置背景图片大小,android页面设置background为图片后,页面滑动掉帧问题...

最近接手的一个android项目里面,有个viewpager3个fragment的页面,就是很常见的可以左右滑动切换页面的那种布局。接手的时候告诉我,这个页面有卡顿现象,性能需要优化。一开始觉得是fragment里面做了太多耗时操作的原因&#xff0c…

企业级项目实战讲解!java的war包能直接改名么

Java核心架构笔记大致如下 0~1年: Java基础(基本语法、面向对象、继承、多态、接口和抽象类、异常、内部类、集合、泛型、反射、I/O等)Web编程(ServletMySQL数据库商品管理系统实战)SSM框架入门到精通(Sp…

android chrome cast,有了它 任何安卓设备瞬间变身ChromeCast

ChromeCast一经问世就颇受欢迎,虽然35美刀的价格已经很便宜了,但现在你可以不花一分钱就可以拥有ChromeCast类似的功能了。前提是你有一部系统版本在2.2以上的安卓设备,对于很多安卓的玩家这应该不是什么问题。实现与ChromeCast类似的功能只需…

企业级项目实战讲解!java类内部定义枚举

蚂蚁一面 ⼀⾯就做了⼀道算法题,要求两⼩时内完成,给了⻓度为N的有重复元素的数组,要求输出第10⼤的数。典型的TopK问题,快排算法搞定。算法题要注意的是合法性校验、边界条件以及异常的处理。另外,如果要写测试⽤例&…

荣耀鸿蒙价格,荣耀40S秀肌肉,120Hz+双5000万+鸿蒙系统,售价很感人

原标题:荣耀40S秀肌肉,120Hz双5000万鸿蒙系统,售价很感人虽然现在有不少的手机厂商开始发展子品牌,比如vivo发展的iQOO以及OPPO发展的真我,都是在市场上开始冒头。不过知名度最高的还是荣耀这个子品牌,自从…

作为Java开发程序员,中科创达java应届生薪资

01 并发宝典:面试专题 面试专题分为四个部分,分别如下 Synchronized 相关问题 可重入锁 ReentrantLock 及其他显式锁相关问题 Java 线程池相关问题 Java 内存模型相关问题 1.1 Synchronized 相关问题(这里整理了八问) 问题一…

Java面试必备的集合源码详解,砥砺前行!

一面(一个小时左右) 算法:写冒泡排序,问如何优化,简单讲了快排和堆排序的原理数据库:解释左连接数据库第一第二第三范式,数据库死锁linux:怎么查看内存;怎么查看进程&am…

android md 控件,Android基本UI控件.md

# Android基本UI控件## *TextView 文本框*### TextView常用用法| 主要方法 | 功能描述 || :----------: | :--------------------: || getText | 获得TextView对象的文本 || setText | 设置TextView对象的文本 || setTextColor | 设置文本显示的颜色 |Javaprivate TextView tex…

java面试核心知识点,详解系列文章

技术能力 通常,「技术能力」这个部分将紧接着你的个人简介之后,放在简历的核心版面。这样设计是有道理的,因为它能够帮助雇主更快的判断你的技能是否与需求相吻合。 因此在制作这一部分内容时,你应该考虑以下两点: …

html5跨平台桌面打包,Html5到跨平台app应用

Html5到跨平台app应用每一项新兴技术的出现和流行,都是为了规模化的去统一解决一系列复杂问题,APICloud选择混合开发方向,目的是希望借助HTML5降低app开发复杂度,提高app开发效率。通过工程化的实践手段,我们首先设计了…

Java面试知识点总结宝典助你通关!成功入职字节跳动

01 阿里中间件(四面,Java岗) 1.1 Java中间件一面 技术一面考察范围 重点问了Java线程锁:synchronized 和ReentrantLock相关的底层实现 线程池的底层实现以及常见的参数 数据结构基本都问了一遍:链表、队列等 Java内存…

html第二章课后选择题答案,HTML课后习题(带答案).doc

HTML课后习题选择题1. 下列标签中,用于设置字体大小、颜色的标签是(D)A. bB. subC. supD. font关于下列代码片段,说法错误的是(A)A. 用于在HTML文档中插入图像链接B. 图像以100100的大小显示C. 标签用于在页面中显示一张图像D. 图像的对齐方式为左对齐3.…

那些年的随笔

平安夜,没有下雪,也不冷,也没有女朋友。不知道来年是否会幸福。 单身这么多年,工作这么多年,知道了孤独,知道了辛苦,知道了人情冷暖。 我们每个人都有着自己的幸福选择。有的人追寻着此时此刻…

Java面试题及答案,java入门书籍

天下码农,多为CV!你是否每天还在增删改查?性能优化让你手足无措?看这里!技术大牛带你分分钟完爆性能优化!!! Java性能权威指南淘宝千万并发性能优化实战!理论结合实战&am…

隐藏导航条HTML,jQuery实现的导航条切换可显示隐藏

用jQuery实现一些导航条切换,显示隐藏,主要运用的技术有slideToggle( ),toggeClass( ),toggle( ):代码如下:导航条在项目中的应用$(function(){$(".tit").find("span").click(function(){$(this).…