《深入理解linux静态库与动态库》
来源:互联网 发布:tts软件 编辑:程序博客网 时间:2024/06/05 15:24
动态库和静态库作为两种不同的解决程序代码复用(为了复用而在内存中的存在方式)的手段而并行不悖,各有千秋
前者动态绑定(运行期),节约空间,利于维护
后者静态绑定(编译期),独立运行,不产生运行依赖
下面以示例来说明:
先看静态库
/*************************************************************************> File Name: sxyqe.cpp> Author: XXDK> Email: v.manstein@qq.com > Created Time: Sun 24 Sep 2017 06:10:41 PM CST ************************************************************************/#include<iostream>using namespace std;void sxyqe(void){cout << "山下一群鹅," << endl;}
/*************************************************************************> File Name: xsglh.cpp> Author: XXDK> Email: v.manstein@qq.com > Created Time: Sun 24 Sep 2017 06:13:18 PM CST ************************************************************************/#include<iostream>using namespace std;void xsglh(void){cout << "嘘声赶落河。" << endl;}
将 sxyqe.cpp 和 xsglh.cpp 编译为静态库:
g++ -c sxyqe.cpp xsglh.cpp
ar rcs libA.a sxyqe.o xsglh.o查看:
nm -a libA.a
sxyqe.o:0000000000000000 b .bss0000000000000000 n .comment U __cxa_atexit0000000000000000 d .data U __dso_handle0000000000000000 r .eh_frame0000000000000061 t _GLOBAL__sub_I__Z5sxyqev0000000000000000 t .init_array0000000000000000 n .note.GNU-stack0000000000000000 r .rodata0000000000000000 a sxyqe.cpp0000000000000000 t .text0000000000000023 t _Z41__static_initialization_and_destruction_0ii0000000000000000 T _Z5sxyqev U _ZNSolsEPFRSoS_E U _ZNSt8ios_base4InitC1Ev U _ZNSt8ios_base4InitD1Ev U _ZSt4cout U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_0000000000000000 b _ZStL8__ioinit U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKcxsglh.o:0000000000000000 b .bss0000000000000000 n .comment U __cxa_atexit0000000000000000 d .data U __dso_handle0000000000000000 r .eh_frame0000000000000061 t _GLOBAL__sub_I__Z5xsglhv0000000000000000 t .init_array0000000000000000 n .note.GNU-stack0000000000000000 r .rodata0000000000000000 t .text0000000000000000 a xsglh.cpp0000000000000023 t _Z41__static_initialization_and_destruction_0ii0000000000000000 T _Z5xsglhv U _ZNSolsEPFRSoS_E U _ZNSt8ios_base4InitC1Ev U _ZNSt8ios_base4InitD1Ev U _ZSt4cout U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_0000000000000000 b _ZStL8__ioinit U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
可以看到尽管我们将这两个源文件编译为静态库形式,U 标识的项依然是依赖于c++的动态库,也就
是该静态库依赖于c++标准库,链接过程中会去c++库查找符号如:cout
-----------------------------------------------------------------------------------------------------------------------------------
接下来是动态库/*************************************************************************> File Name: lhzeyde.cpp> Author: XXDK> Email: v.manstein@qq.com > Created Time: Sun 24 Sep 2017 06:31:18 PM CST ************************************************************************/#include<iostream>using namespace std;void lhzeyde(void){cout << "落河捉鹅医肚饿," << endl;}
/*************************************************************************> File Name: cwhjwlp.cpp> Author: XXDK> Email: v.manstein@qq.com > Created Time: Sun 24 Sep 2017 06:33:09 PM CST ************************************************************************/#include<iostream>using namespace std;void cwhjwlp(void){cout << "吃完回家玩老婆。" << endl;}
将lhzeyde.cpp 和 cwhjwlp.cpp 编译为动态库:
gcc -fPIC -shared -o libB.so lhzeyde.cpp cwhjwlp.cpp
查看:
nm -a libB.so
0000000000000000 a 0000000000201040 b .bss0000000000201040 B __bss_start0000000000000000 n .comment0000000000201040 b completed.75850000000000000000 a crtstuff.c0000000000000000 a crtstuff.c0000000000000000 a cwhjwlp.cpp U __cxa_atexit@@GLIBC_2.2.5 w __cxa_finalize@@GLIBC_2.2.50000000000201038 d .data0000000000000810 t deregister_tm_clones00000000000008a0 t __do_global_dtors_aux0000000000200df0 t __do_global_dtors_aux_fini_array_entry0000000000201038 d __dso_handle0000000000200e00 d .dynamic0000000000200e00 d _DYNAMIC0000000000000428 r .dynstr0000000000000230 r .dynsym0000000000201040 D _edata0000000000000ab0 r .eh_frame0000000000000a6c r .eh_frame_hdr0000000000201048 B _end0000000000000a30 T _fini0000000000000a30 t .fini0000000000200df0 t .fini_array00000000000008e0 t frame_dummy0000000000200dd8 t __frame_dummy_init_array_entry0000000000000bb0 r __FRAME_END__0000000000201000 d _GLOBAL_OFFSET_TABLE_0000000000000a1b t _GLOBAL__sub_I_cwhjwlp.cpp000000000000098b t _GLOBAL__sub_I_lhzeyde.cpp w __gmon_start__0000000000000a6c r __GNU_EH_FRAME_HDR00000000000001f0 r .gnu.hash00000000000005ae r .gnu.version00000000000005d8 r .gnu.version_r0000000000200fc0 d .got0000000000201000 d .got.plt0000000000000790 T _init0000000000000790 t .init0000000000200dd8 t .init_array w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable0000000000200df8 d .jcr0000000000200df8 d __JCR_END__0000000000200df8 d __JCR_LIST__ w _Jv_RegisterClasses0000000000000000 a lhzeyde.cpp00000000000001c8 r .note.gnu.build-id00000000000007b0 t .plt0000000000000800 t .plt.got0000000000000850 t register_tm_clones00000000000005f8 r .rela.dyn0000000000000730 r .rela.plt0000000000000a39 r .rodata0000000000000810 t .text0000000000201040 d __TMC_END__0000000000000942 t _Z41__static_initialization_and_destruction_0ii00000000000009d2 t _Z41__static_initialization_and_destruction_0ii00000000000009a0 T _Z7cwhjwlpv0000000000000910 T _Z7lhzeydev U _ZNSolsEPFRSoS_E U _ZNSt8ios_base4InitC1Ev U _ZNSt8ios_base4InitD1Ev U _ZSt4cout U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_0000000000201041 b _ZStL8__ioinit0000000000201042 b _ZStL8__ioinit U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
同样从U标识的未定义符号可以看到,该动态库依赖于c++动态库
/*************************************************************************> File Name: main.cpp> Author: XXDK> Email: v.manstein@qq.com > Created Time: Sun 24 Sep 2017 06:43:53 PM CST ************************************************************************/#include<iostream>#include"sxyqe.h"#include"xsglh.h"#include"lhzeyde.h"#include"cwhjwlp.h"using namespace std;int main(){cout << "===================================================================" << endl;cout << "祝枝山:今天我们江南四大才子到这里游山玩水,难怪那些女子要疯狂了。" << endl;cout << "~~~~~~:说得是," << endl;cout << "文征明:各位各位,既然大家今天兴致这么好,不如来吟首诗如何? " << endl;cout << "祝枝山:哎,征明兄提议的好啊。文斌兄你先来。 " << endl;cout << "文 斌:"; sxyqe(); cout << "文征明:";xsglh();cout << "祝枝山:";lhzeyde();cout << "唐伯虎:";cwhjwlp();cout << "三 人:哎呀,对得妙呀,真是绝句!" << endl;cout << "唐伯虎:啊哈哈" << endl;cout << "===================================================================" << endl;return 0;}
测试:
g++ main.cpp -I../libar -I../libso -L../libar -L../libso -lA -lB -o main
如果多个库之间有依赖,为确保依赖次,序应该将被依赖的库放在该库之前
结果:
附: nm 各输出项含义
For each symbol, nm shows:The symbol value, in the radix selected by options (see below), or hexadecimal by default.The symbol type. At least the following types are used; others are, as well, depending on the object file format. If lowercase, the symbol is usually local; if uppercase, the symbol is global (external). There are however a few lowercase symbols that are shown for special global symbols (u, v and w).--AThe symbol’s value is absolute, and will not be changed by further linking.--BbThe symbol is in the uninitialized data section (known as BSS).--CThe symbol is common. Common symbols are uninitialized data. When linking, multiple common symbols may appear with the same name. If the symbol is defined anywhere, the common symbols are treated as undefined references. For more details on common symbols, see the discussion of –warn-common in Linker options in The GNU linker.--DdThe symbol is in the initialized data section.--G gThe symbol is in an initialized data section for small objects. Some object file formats permit more efficient access to small data objects, such as a global int variable as opposed to a large global array.--iFor PE format files this indicates that the symbol is in a section specific to the implementation of DLLs. For ELF format files this indicates that the symbol is an indirect function. This is a GNU extension to the standard set of ELF symbol types. It indicates a symbol which if referenced by a relocation does not evaluate to its address, but instead must be invoked at runtime. The runtime execution will then return the value to be used in the relocation.--IThe symbol is an indirect reference to another symbol.--NThe symbol is a debugging symbol.--pThe symbols is in a stack unwind section.--R rThe symbol is in a read only data section.--S sThe symbol is in an uninitialized data section for small objects.--T tThe symbol is in the text (code) section.--UThe symbol is undefined.--uThe symbol is a unique global symbol. This is a GNU extension to the standard set of ELF symbol bindings. For such a symbol the dynamic linker will make sure that in the entire process there is just one symbol with this name and type in use.--V vThe symbol is a weak object. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked and the symbol is not defined, the value of the weak symbol becomes zero with no error. On some systems, uppercase indicates that a default value has been specified.--W wThe symbol is a weak symbol that has not been specifically tagged as a weak object symbol. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked and the symbol is not defined, the value of the symbol is determined in a system-specific manner without error. On some systems, uppercase indicates that a default value has been specified. -The symbol is a stabs symbol in an a.out object file. In this case, the next values printed are the stabs other field, the stabs desc field, and the stab type. Stabs symbols are used to hold debugging information. ?The symbol type is unknown, or object file format specific.
- 深入理解Linux静态库与动态库
- 《深入理解linux静态库与动态库》
- 静态库与动态库的理解
- 深入理解C语言----动态库 & 静态库 & 链接
- 深入理解静态链接库和动态链接库
- 深入理解动态库
- 深入理解动态库
- 深入理解动态库
- 深入理解动态库
- 深入理解JVM之七:静态分派与动态分派
- 深入理解JVM之七:静态分派与动态分派
- 深入理解JVM之七:静态分派与动态分派
- 深入理解iPhone静态库
- 深入理解iPhone静态库
- 深入理解iPhone静态库
- 深入理解iPhone静态库
- 深入理解iPhone静态库
- 动态库与静态库的深入分析
- 【NOIP】时间将尽の模板集合
- hdu2063(最大权匹配匈牙利算法模板)
- Longest Substring Without Repeating Characters
- Centos 下安装redmine
- 【CS 1380】没有上司的舞会(树形dp+dfs)
- 《深入理解linux静态库与动态库》
- 2017年南宁网络赛 L 题 【最长非递减序列 + 思维】
- c++ 合并两个无序顺序表使其仍无序
- 奶牛送苹果
- JSON入门Java篇-2-JSON数据类型
- 路径
- HDU3652 数位DP 记忆化搜索
- 使用playframework连接MySql
- NOIP1998提高组 车站