Linux GCC编译使用动态、静态链接库 (转)
原文出处:http://blog.csdn.net/a600423444/article/details/7206015
在windows下动态链接库是以.dll后缀的文件,二在Linux中,是以.so作后缀的文件。
动态链接库的好处就是节省内存空间。
1、Linux下创建动态链接库
在使用GCC编译程序时,只需加上-shared选项即可,这样生成的执行程序即为动态链接库。
例如有文件:hello.c x.h main.c
- 编译:gcc hello.c -fPIC -shared -o libhello.so
其中-fPIC选项的作用是:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的,
所以动态载入时是通过代码拷贝的方式来满足不同的调用,而不能达到真正的代码段共享的目的.
将main.c与hello.so动态库
- gcc main.c -L. -lhello -o main
一、动态链接库
1.创建hello.so动态库
- #include <stdio.h>
- void hello(){
- printf("hello world\n");
- }
- 编译:gcc -fPIC -shared hello.c -o libhello.so
2.hello.h头文件
- void hello();
3.链接动态库
- #include <stdio.h>
- #include "hello.h"
- int main(){
- printf("call hello()");
- hello();
- }
- 编译:gcc main.c -L. -lhello -o main
这里-L的选项是指定编译器在搜索动态库时搜索的路径,告诉编译器hello库的位置。"."意思是当前路径.
3.编译成够后执行./main,会提示:
- In function `main':
- main.c:(.text+0x1d): undefined reference to `hello'
- collect2: ld returned 1 exit status
这是因为在链接hello动态库时,编译器没有找到。
解决方法:
- sudo cp libhello.so /usr/lib/
这样,再次执行就成功输入:
call hello()
二、静态库
文件有:main.c、hello.c、hello.h
1.编译静态库hello.o:
- gcc hello.c -o hello.o #这里没有使用-shared
2.把目标文档归档
- ar -r libhello.a hello.o #这里的ar相当于tar的作用,将多个目标打包。
程序ar配合参数-r创建一个新库libhello.a,并将命令行中列出的文件打包入其中。这种方法,如果libhello.a已经存在,将会覆盖现在文件,否则将新创建。
3.链接静态库
- gcc main.c -lhello -L. -static -o main
这里的-static选项是告诉编译器,hello是静态库。
或者:
- gcc main.c libhello.a -L. -o main
这样就可以不用加-static
4.执行./main
输出:call hello()
三、借助自带的ldd实现程序来分析动态库搜索情况
ldd main
结果:
linux-gate.so.1 => (0x00efd000)
libhello.so => /usr/lib/libhello.so (0x00f6b000)
libc.so.6 => /lib/libc.so.6 (0x001a5000)
/lib/ld-linux.so.2 (0x00eb8000)
如果目标程序没有链接动态库,则打印“not a dynamic executable”
Linux GCC编译使用动态、静态链接库 (转)的更多相关文章
- Linux环境下c语言静态链接库和动态链接库创建和使用
库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀. 面对比一下两者: 静态链接库:当要使用时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功, ...
- linux下动态链接库.so文件 静态链接库.a文件创建及使用
转摘网址为:http://www.cnblogs.com/fengyv/archive/2012/08/10/2631313.html Linux下文件的类型是不依赖于其后缀名的,但一般来讲: ...
- linux gcc 编译时头文件和库文件搜索路径
一.头文件 gcc 在编译时寻找所需要的头文件 : ※搜寻会从-I开始 ※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INC ...
- VS2010编译Boost 1.57 静态链接库
http://www.cnblogs.com/cuish/p/4175491.html 0.前提 Boost库版本 1.57.0 下载地址 http://www.boost.org/users/his ...
- 利用GCC编译器生成动态链接库和静态链接库
转载请标明:http://www.cnblogs.com/winifred-tang94/ 1.编译过程 gcc –fPIC –c xxx.c 其中-fPIC是通知gcc编译器产生位置独立的目标代码. ...
- App开发流程之数据持久化和编译静态链接库
先记录数据持久化. iOS客户端提供的常用数据持久化方案:NSUserDefaults代表的用户设置,NSKeydArchiver代表的归档,plist文件存储,SQLite数据库(包括上层使用的Co ...
- 动态链接库dll,导入库lib,静态链接库lib
目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库” ...
- VC++ DLL 2 静态链接库
这一篇以VS2013为例子介绍怎样编写一个静态链接库和调用. 1.打开VS2013,新建Visual C++ 的win32项目: 新建后工程分支如下: 添加头文件和源文件: 编写头文件和源文件内容: ...
- GCC 编译使用动态链接库和静态链接库
1 库的分类 根据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行. 有 ...
随机推荐
- 【APP接口开发】chrome浏览器DHC工具安装使用(亲测有效)
1.DHC文件获取地址:http://chromecj.com/web-development/2015-08/549/download.html 2.chrome安装DHC插件教程和步骤:http: ...
- 一对一关系数据库表 java类描述
一对一关系中 从表的主键是 主表的外键 sql语句 create table person( id int primary key, name varchar(100) ); create table ...
- Axure 蚂蚁设计团队组件库 让交互稿美美"搭"
Github资源:https://github.com/ant-design/ant-design-pro English | 简体中文 技术实践篇 https://pro.ant.design/do ...
- 如何在C++中调用C程序
注意这里的C调用C++或者C++调用C意思是.c文件中调用.cpp文件中代码,或者相反. C++和C是两种完全不同的编译链接处理方式,如果直接在C++里面调用C函数,会找不到函数体,报链接错误. 要解 ...
- Genymotion INSTALL_FAILED_CPU_ABI_INCOMPATIBLE
出现这个错误的原因是Genymotion默认的处理器是x86的,不是arm的.所以安装的时候会出错,仅仅要把x86转换成arm就能够了. 转换方法: 1.下载转换的zip文件:X86 to ARM 2 ...
- Java中path,-classpath,-Djava.library.path的功能和区别
1. path path是个系统环境变量,声明命令的搜索路径,让操作系统找到指定的工具程序. D:\Program Files\Java\jdk1.8.0_111\bin指定JDK工具路径,例如jav ...
- webapi应用架构详解
webapi适用场景 常见的应用包括以下四类,PC客户端程序,APP程序,网站程序,H5程序.这些应用需要的数据,服务可由同一个接口服务程序提供,这样,大大提高了产品多平台设计开发的效率,避免了重复的 ...
- 每日英语:Air Pollution From Coal Use Cuts Lifespans in China, Study Shows
Air pollution from coal combustion likely cut life expectancy in parts of China by more than five ye ...
- 删除CNNIC根证书
操作方法: 1.点击IE工具菜单-->选项-->内容-->证书,在受信任的根证书颁发机构中找到CNNIC Root,将证书导出到桌面备用. 双击CNNIC ROOT查看这个证书的属性 ...
- mysql 从一个表中查询插入另一个表
insert into dnt_userfields (uid,realname ) select uid,nickname from discuz.dnt_users where uid>72 ...