《深入理解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.
--B
bThe symbol is in the uninitialized data section (known as BSS).
--C
The 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.
--D
dThe 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.



 
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 换驾驶证但是身份证地址变动怎么办 驾驶证b证扣分了怎么办 c1驾证过期没审怎么办 驾照报名三年过期了怎么办 新车行驶证过期了怎么办 行驶证忘了审怎么办 摩托车驾驶证副本丢了怎么办 人被全险车撞了怎么办 被全险车撞了怎么办 驾驶证和行驶证遗失怎么办 户口迁移身份证没换驾照怎么办 户口迁回时身份证掉了怎么办 户口毕业托管身份证掉了怎么办 身份证和户口都掉了怎么办 毕业生户口迁回原籍没身份证怎么办 落户上海后怎么办医保卡 小车临时牌过期了怎么办 驾驶证地址错了一个字怎么办 驾驶证名下车辆有违章怎么办 a2如果扣12分怎么办 b2一次超速12分怎么办 b2本扣了12分怎么办 驾照扣了27分怎么办 大车一次扣12分怎么办 a2驾照扣10分怎么办 驾驶证强制降级没给驾驶证怎么办 6P升11.2卡了怎么办 b2驾照记满12分怎么办 c1驾驶证没分了怎么办 驾照扣了15分怎么办 驾驶证暂扣六个月后怎么办 醉驾交警不通知怎么办 参军后地方驾驶证年审怎么办 军人驾驶证到期身份证注销了怎么办 资格证脱审30天怎么办 驾驶证c证扣6分怎么办 驾照被扣了9分怎么办 驾驶证被扣了9分怎么办 a2驾驶本扣3分怎么办 c1e没过扣了满分怎么办 c1一下扣12分怎么办