C/C++编程中相关文件后缀(以Linux系统下为例):

.a:           静态库(archive)

.c/.cpp:  C/C++源程序

.h/.hpp: C/C++源程序的头文件

.i:           经过预处理后的C/C++源程序

.o:        对象文件

.s:        汇编语言代码

.so:      动态链接库

本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存运行。库有两种:静态库(Linux操作系统下是以.a做后缀,Windows操作系统下以.lib做后缀)和动态库(Linux操作系统下是以.so做后缀,Windows操作系统下以.dll做后缀)。

静态库是编译器生成的.o对象文件的集合,静态库另外一个名字叫归档文件(archive),管理这种归档文件的工具叫ar.

常用的编译命令(命令行编译C源程序使用gcc,编译C++源程序使用g++,此处以g++编译C++源程序为例):

假设需要编译的源程序有hello.cpp和world.cpp,则

1. $g++ -Wall hello.cpp                              这是最简单的编译命令,-Wall是 warn all的缩写,即显示在编译过程中的所有警告信息。编译器编译源代码文件生成对象文件.o, 链接对象文件得到可执行文件,并删除对象文件。由于此处未指定可执行程序的文件名,编译器默认输出a.out

2. $g++ -Wall hello.cpp -o hello                   此处使用-o指定输出的可执行文件的名字,-o代表output。

3. $g++ -c -Wall hello.cpp  -o hello              选项-c 表示compile, 指示编译器只完成编译过程生成对象文件,不执行链接过程。

4. $g++ -c -Wall hello.cpp world.cpp            此命令可以一次性生成多个对象文件

5. $g++ -c -Wall hello.cpp world.cpp -o hello 此命令将两个源文件分别编译为对象文件且将其链接为可执行文件hello

6. $g++ -E hello.cpp -o hello.i                      选项-E这是编译器只进行预编译处理

7. $g++ -S hello.cpp   -o hello.s                   此命令生成汇编代码

Linux环境下创建并使用静态库:

要创建一个静态库,首先要编译出库中需要的对象文件,则:

1.$g++ -c -Wall hello.cpp world.cpp

指令ar配合参数-crv可以创建一个新库并将之前创建好的对象文件插入。如果库不存在,则参数-r将创建一个新库,并将对象模块添加到归档文件中。下面的命令将创建一个包含上述两个对象文件的名为libhelloworld.a的静态库:

2.$ar -crv libhelloworld.a hello.o world.o   比较大的项目会编写makefile文件来生成静态库。

Linux静态库命名规范,必须是lib[your_library_name].a,其中lib为前缀,中间是静态库名,扩展名为.a

3. Linux下使用静态库,只需要在编译的时候,指定静态库的搜索路径(-L选项),指定静态库名(不需要lib前缀和.a后缀,-l选项),假设打包生成的libhelloworld.a静态库放在../StatiLibrary目录下,则:

$g++ testStaticLibrary.cpp -L ../StaticLibrary -l helloworld  编译生成可执行文件

Linux环境下创建并使用动态库:

1.为什么要使用动态库? 因为:1.使用静态库会造成空间浪费。2. 静态库对程序的更新,部署和发布带来麻烦,如果静态库libhelloworld.a更新了,所有使用它的应用程序都需要重新编译,发布给用户。

动态库在程序编译时并不会被链接到目标文件中,而是在程序运行时才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要一份该共享库的实例,规避了空间浪费问题。

2. 动态链接库的命名形式为lib[your_library_name].so,前缀是lib,后缀是.so。在文件系统中,your_library_name仅是一个链接到实际动态库的链接。对于动态库而言,每个库实际上都有另一个名字给编译器使用,它是一个指向库镜像文件的链接文件lib[your_library_name].so

3. 创建动态库的过程中,首先生成目标文件,此时要加编译器选项-fPIC

$g++ -fPIC -c hello.cpp world.cpp   -fPIC创建与地址无关的编译程序(pic:position independent code),是为了能够在多个应该程序间共享。

4. 生成动态库,此时要加链接器选项-shared

$g++ -shared -o libhelloworld.so hello.o world.o

5. 引用动态库编译成可行文件(跟静态库文件一样):
$g++ testStaticLibrary.cpp -L ../StaticLibrary -l helloworld

发现报错了!!!那么,在执行的时候是如何定位共享库文件的呢?

1)        当系统加载可执行代码时候,能够知道其所依赖的库的名字,但是还需要知道绝对路径。此时就需要系统动态载入器(dynamic linker/loader)。

2)        对于elf格式的可执行程序,是由ld-linux.so*来完成的,它先后搜索elf文件的 DT_RPATH段—环境变量LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/,/usr/lib 目录找到库文件后将其载入内存。

如何让系统能够找到它:

l  如果安装在/lib或者/usr/lib下,那么ld默认能够找到,无需其他操作。

l  如果安装在其他目录,需要将其添加到/etc/ld.so.cache文件中,步骤如下:

n  编辑/etc/ld.so.conf文件,加入库文件所在目录的路径

n  运行ldconfig ,该命令会重建/etc/ld.so.cache文件

我们将创建的动态库复制到/usr/lib下面,然后运行测试程序。

C/C++的静态库与动态库的更多相关文章

  1. C++ 系列:静态库与动态库

    转载自http://www.cnblogs.com/skynet/p/3372855.html 这次分享的宗旨是——让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择 ...

  2. C++静态库与动态库

    C++静态库与动态库 这次分享的宗旨是--让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学,推荐一 ...

  3. Linux下Gcc生成和使用静态库和动态库详解(转)

    一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...

  4. Makefile中静态库,动态库的创建和使用以及解压缩命令

    应用层通过操作文件操控硬件 使用制作好的工具链: 刚开始学习时,用一些已经制作好的工具链,使用以下命令解压到gcc-3.4.5-glibc-2.3.6目录 cd /work/tools tar xjf ...

  5. VS中Debug和Realease、及静态库和动态库的区别整理(转)

    原文出自:http://www.cnblogs.com/chensu/p/5632486.html 一.Debug和Realease区别产生的原因 Debug 通常称为调试版本,它包含调试信息,并且不 ...

  6. Linux下C++静态库、动态库的制作与使用

    参考博文:C++静态库与动态库 >> 静态库 1. 静态库的制作 a) 编辑 name.cpp 和name.h文件 b) $g++ -c name.cpp //注意带参数-c,否则直接编译 ...

  7. 在Linux下如何使用GCC编译程序、简单生成 静态库及动态库

      最近在编写的一个Apache  kafka 的C/C++客户端,,在看他写的 example中,他的编译是用librdkafka++.a和librdkafka.a    静态库编译的,,,而我们这 ...

  8. VS中Debug和Realease、及静态库和动态库的区别整理

    一.Debug和Realease区别产生的原因 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进行了各种优化,使得程序在代码 ...

  9. Linux下Gcc生成和使用静态库和动态库详解

    参考文章:http://blog.chinaunix.net/uid-23592843-id-223539.html 一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库 ...

  10. android开发 NDK 编译和使用静态库、动态库 (转)

    在eclipse工程目录下建立一个jni的文件夹 在jni文件夹中建立Android.mk和Application.mk文件 Android.mk文件: Android提供的一种makefile文件, ...

随机推荐

  1. 常用的HTTP方法

    方法                 描述 是否包含主体 GET  从服务器获得一份文档 否 HEAD  只从服务器获得响应报文的首部 否 POST  向服务器发送需要处理的数据 是 PUT  将请求 ...

  2. mysql报错1024-can't get hostname for your address

    前一段时间mysql用的好好的,突然一天,mysql启动后,在使用navicat连接数据库的时候 报错1024-can't get hostname for your address 这里我是这样解决 ...

  3. php 语言特点

    PS:绝大多数用php的企业/ 项目 活不到雇佣得起月薪35k以上的php程序员那一天,也是php码农在10年经验的时候普遍不如java程序员的原因之一. PS2: 由于薪资提升太快,很多php码农跳 ...

  4. python 数组过滤

    arr = [1,2,3,4,5,6,7,8,None]arr = [elem for elem in arr if elem != None]

  5. CoreJavaE10V1P3.7 第3章 Java的基本编程结构-3.7 输入输出(Input ,Output)

    3.7.1 读取输入 Scanner in = new Scanner(System.in); System.out.print("What is your name? "); S ...

  6. B+树概念学习

    转载自 从B树.B+树.B*树谈到R 树 1.用阶定义的B树 B 树又叫平衡多路查找树.一棵m阶的B 树 (注:切勿简单的认为一棵m阶的B树是m叉树,虽然存在四叉树,八叉树,KD树,及vp/R树/R* ...

  7. NGINX----源码阅读---sources配置脚本

    /auto/sources 本文件主要用于对源文件环境变量进行初始化,主要包括:.c和.h文件. 对应变量类型有*_MODULES.*_INCS.*_DEPS等. # Copyright (C) Ig ...

  8. thinkphp5.0 自动加载

    自动加载 概述 ThinkPHP5.0真正实现了按需加载,所有类库采用自动加载机制,并且支持类库映射和composer类库的自动加载. 自动加载的实现由think\Loader类库完成,自动加载规范符 ...

  9. Linq 内联左联等

    我们在做SQL查询的时候经常会用到Inner Join,Left Join,笛卡尔积等等,连接方式的概念方面我想也不用给予太多解释, 我们今天的重点是让大家熟悉LINQ是如何使用Join来实现常用的表 ...

  10. Hive 执行计划

    执行语句 hive> explain select s.id, s.name from student s left outer join student_tmp st on s.name = ...