Linux 静态链接库和动态连接库
(0)文件夹
一:静态链接库的应用 三步走~~~
##g++ -c StaticMath.cpp
##ar -crv libstaticmath.a StaticMath.o
##g++ -o run test_a.cpp -L. -lstaticmath
#[@sjs_37_33 lib_A_SO]# ./run
a + b = 12
a - b = 8
a * b = 20
a / b = 5
**********************
**********************
sh: pause: command not found
**********************
二:走的弯路~~~~
#[@sjs_37_33 lib_A_SO]# g++ -o run test_a.cpp // 缺少依赖库文件
/tmp/ccx8rZph.o: In function `main':
test_a.cpp:(.text+0x39): undefined reference to `StaticMath::add(double, double)'
test_a.cpp:(.text+0x76): undefined reference to `StaticMath::sub(double, double)'
test_a.cpp:(.text+0xb3): undefined reference to `StaticMath::mul(double, double)'
test_a.cpp:(.text+0xf0): undefined reference to `StaticMath::div(double, double)'
test_a.cpp:(.text+0x12a): undefined reference to `StaticMath::StaticMath()'
test_a.cpp:(.text+0x136): undefined reference to `StaticMath::print()'
test_a.cpp:(.text+0x151): undefined reference to `StaticMath::~StaticMath()'
test_a.cpp:(.text+0x16d): undefined reference to `StaticMath::~StaticMath()'
collect2: ld ?μ?? 1
#[@sjs_37_33 lib_A_SO]# g++ -o run test_a.cpp -L. -lstaticmath // 缺少依赖库?非也。缺少实现函数即.cpp没有实现.h中的文件
/tmp/cczojb8v.o: In function `main':
test_a.cpp:(.text+0x12a): undefined reference to `StaticMath::StaticMath()'
test_a.cpp:(.text+0x151): undefined reference to `StaticMath::~StaticMath()'
test_a.cpp:(.text+0x16d): undefined reference to `StaticMath::~StaticMath()'
collect2: ld ·μ?
? 1
三: 动态库的应用 两步走~~·
### g++ -fPIC -shared -o libdynmath.so StaticMath.cpp ---- 生成-o libdynmath.so 动态库
引用动态库编译成可运行文件(跟静态库方式一样):
###g++ TestDynamicLibrary.cpp -L../DynamicLibrary -ldynmath
然后执行:./a.out,发现居然报错了!
。!
#[@sjs_37_33 lib_A_SO]# ./a.out
./a.out: error while loading shared libraries: libdynmath.so: cannot open shared object file: No such file or directory
那么,在运行的时候是怎样定位共享库文件的呢?
1) 当系统载入可运行代码时候,可以知道其所依赖的库的名字。可是还须要知道绝对路径。
此时就须要系统动态载入器(dynamic linker/loader)。
2) 对于elf格式的可运行程序。是由ld-linux.so*来完毕的。它先后搜索elf文件的 DT_RPATH段—环境变量LD_LIBRARY_PATH—/etc/ld.so.cache文件列表—/lib/,/usr/lib 文件夹找到库文件后将其加载内存。
怎样让系统可以找到它:
假设安装在/lib或者/usr/lib下,那么ld默认可以找到。无需其它操作;假设安装在其它文件夹。须要将其加入到/etc/ld.so.cache文件里。过程例如以下:
编辑/etc/ld.so.conf文件,增加库文件所在文件夹的路径。执行ldconfig 。该命令会重建/etc/ld.so.cache文件;我们将创建的动态库拷贝到/usr/lib以下,然后执行測试程序,成功。
四: Linux下库相关命令
##ldd libdynmath.so
linux-vdso.so.1 => (0x00007fffed837000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f48b0413000)
libm.so.6 => /lib64/libm.so.6 (0x00007f48b018e000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f48aff78000)
libc.so.6 => /lib64/libc.so.6 (0x00007f48afbe8000)
/lib64/ld-linux-x86-64.so.2 (0x0000003da7800000)
g++(gcc)编译选项
-shared :指定生成动态链接库。
-static :指定生成静态链接库。
-fPIC :表示编译为位置独立的代码,用于编译共享库。目标文件须要创建成位置无关码, 念上就是在可运行程序装载它们的时候,它们能够放在可运行程序的内存里的不论什么地方。
-L. :表示要连接的库所在的文件夹。
-l:指定链接时须要的动态库。
编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib。后面加上.a/.so来确定库的名称。
-Wall :生成全部警告信息。
-ggdb :此选项将尽可能的生成gdb 的能够使用的调试信息。
-g :编译器在编译的时候产生调试信息。
-c :仅仅激活预处理、编译和汇编,也就是把程序做成目标文件(.o文件) 。
-Wl,options :把參数(options)传递给链接器ld 。
假设options 中间有逗号,就将options分成多个选项,然后传递给链接程序。
nm命令
有时候可能须要查看一个库中究竟有哪些函数,nm命令能够打印出库中的涉及到的全部符号。
库既能够是静态的也能够是动态的。
nm列出的符号有非常多,常见的有三种:
一种是在库中被调用。但并没有在库中定义(表明须要其它库支持)。用U表示;
一种是库中定义的函数,用T表示,这是最常见的;
一种是所谓的弱态”符号,它们尽管在库中被定义,可是可能被其它库中的同名符号覆盖。用W表示。
$nm libhello.h
ldd命令
ldd命令能够查看一个可运行程序依赖的共享库,比如我们编写的四则运算动态库依赖以下这些库:
打开文件、保存、关闭文件(vi命令模式下使用)
vi filename //打开filename文件
:w //保存文件
:w vpser.net //保存至vpser.net文件
:q //退出编辑器,假设文件已改动请使用以下的命令
:q! //退出编辑器,且不保存
:wq //退出编辑器,且保存文件
五:相关代码
h文件
#pragma once
class StaticMath
{
public:
StaticMath(void);
~StaticMath(void); static double add(double a, double b);//加法
static double sub(double a, double b);//减法
static double mul(double a, double b);//乘法
static double div(double a, double b);//除法 void print();
};
cpp文件
#include "StaticMath.h"
#include <stdio.h> StaticMath::StaticMath(void)
{
//
print();
} StaticMath::~StaticMath(void)
{
//
print();
} double StaticMath::add(double a, double b)//加法
{
return a + b;
}
double StaticMath::sub(double a, double b)//减法
{
return a - b;
} double StaticMath::mul(double a, double b)//乘法
{
return a * b;
}
double StaticMath::div(double a, double b)//除法
{
if(0==b)
return -1;
return a / b;
} void StaticMath::print()
{
printf("**********************\n");
}
測试文件
#include "StaticMath.h" // 測试静态库libstaticmath.a 和 动态库libdynmath.so #include <iostream>
#include <stdlib.h>
using namespace std; int main(int argc, char* argv[])
{
double a = 10;
double b = 2; cout << "a + b = " << StaticMath::add(a, b) << endl;
cout << "a - b = " << StaticMath::sub(a, b) << endl;
cout << "a * b = " << StaticMath::mul(a, b) << endl;
cout << "a / b = " << StaticMath::div(a, b) << endl; StaticMath sm;
sm.print(); system("pause");
return 0;
}
六:总结
静态链接库与动态链接库都是共享代码的方式,假设採用静态链接库。则不管你愿不愿意,lib 中的指令都所有被直接包括在终于生成的 EXE 文件里了。
可是若使用 DLL,该 DLL 不必被包括在终于 EXE 文件里,EXE 文件运行时能够“动态”地引用和卸载这个与 EXE 独立的 DLL 文件。静态链接库和动态链接库的另外一个差别在于静态链接库中不能再包括其它的动态链接库或者静态库。而在动态链接库中还能够再包括其它的动态或静态链接库。动态库就是在须要调用当中的函数时,依据函数映射表找到该函数然后调入堆栈运行。假设在当前project中有多处对dll文件里同一个函数的调用。那么运行时,这个函数仅仅会留下一份拷贝。
可是假设有多处对lib文件里同一个函数的调用,那么运行时,该函数将在当前程序的运行空间里留下多份拷贝,并且是一处调用就产生一份拷贝。
Linux 静态链接库和动态连接库的更多相关文章
- 目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。静态库是一个或者多个obj文件的打包
前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”) ...
- Qt动态连接库/静态连接库创建与使用,QLibrary动态加载库
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt动态连接库/静态连接库创建与使用,QLibrary动态加载库 本文地址:https ...
- Linux下的动态连接库及其实现机制
Linux与Windows的动态连接库概念相似,但是实现机制不同.它引入了GOT表和PLT表的概念,综合使用了多种重定位项,实现了"浮动代码",达到了更好的共享性能.本文对这些技术 ...
- c++调用matlab生成的Dll动态连接库
点击打开链接http://download.csdn.net/detail/nuptboyzhb/4228429 c++调用matlab生成的Dll动态连接库 实验平台: matlab 7.0(R ...
- VS2013 生成sqlite3动态连接库及sqlite3.dll的调用
一,生成sqlite3动态连接库1,去sqlite官网上下载最近的sqlite源码包,解压后得到四个文件:shell.c,sqlite3.c,sqlite3.h,sqlite3ext.h此处还需要sq ...
- c++本地动态连接库代码
c++本地动态连接库代码 1 #pragma once 2 #include "stdafx.h" 3 4 #ifdef PERSON_EXPORTS 5 #define PERS ...
- linux静态链接库与动态链接库详解
一顺便说说了哦 通常情况下,对函数库的链接是放在编译时期(compile time)完成的.所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(e ...
- linux静态链接库
库 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载 ...
- linux c 链接详解3-静态库
3静态库 摘自:Linux C编程一站式学习 透过本节可以学会编译静态链接库的shell脚本! 有时候需要把一组代码编译成一个库,这个库在很多项目中都要用到,例如libc就是这样一个库,我们在不同的程 ...
随机推荐
- 线性基【CF845G】Shortest Path Problem?
Description 给定一张 \(n\) 个点 \(m\) 条边的无向图,一开始你在点 \(1\),且价值为 \(0\) 每次你可以选择一个相邻的点,然后走过去,并将价值异或上该边权 如果在点 \ ...
- leetcode7 Rerver Integer
题意:数字反转 思路:醉了,提交了好几次,难点不在于怎么反转,而是判断是否益处,原题中给的是int,4个字节,32位,开始不知道怎么判断.现在知道了是limits.h中的INT_MIN和INT_MAX ...
- PMP CMM
CMM和PMP是两个不同的概念域,是用来解决不同问题的.我们所说的CMM,准确的说应该是叫做能力成熟度模型,北京猴子说的软件能力成熟度模型实际上应该称为SW-CMM,是CMM的一个子集.PMP可以看做 ...
- RUP你知道多少?
RUP 相信学UML的同学,对此都很耳熟,当然也眼熟,可是,对于RUP,你了解多少呢? 首先,什么是RUP? RUP是Rational UnifiedProcess,统一软件开发过程,是一个面向对象且 ...
- [HDU1542]Atlantis(扫描线+线段树)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- [NOIP 2004] T3 合并果子
居然和BZOJ 1724完全一样o(╯□╰)o #include <bits/stdc++.h> using namespace std; typedef long long ll; in ...
- xtuoj 1233 coins(dp)
Coins Accepted : 120 Submit : 305 Time Limit : 1000 MS Memory Limit : 65536 KB Coins Problem Des ...
- 【模拟】 Codeforces Round #434 (Div. 1, based on Technocup 2018 Elimination Round 1) C. Tests Renumeration
题意:有一堆数据,某些是样例数据(假设X个),某些是大数据(假设Y个),但这些数据文件的命名非常混乱.要你给它们一个一个地重命名,保证任意时刻没有重名文件的前提之下,使得样例数据命名为1~X,大数据命 ...
- 【动态规划技巧题】POJ2229-Sumsets
[题目大意] 把一个数n分成2的指数幂相加的形式,问有几种情况. [思路] 如果当前i为奇数,则必定有至少一个1,可以看作i-1的情形再加上一个1.即f[i]=f[i-1]. 如果当前i为偶数,假设没 ...
- JVM命令-java服务器故障排查
一.top(Linux命令) 执行top命令: (查看进程15477的详细情况,下文用到) 系统信息(前五行): 第1行:Top 任务队列信息(系统运行状态及平均负载),与uptime命令结果相 ...