动态链接库和静态链接库的相互包含问题及实现

动态链接库和静态链接库的基本概念请参考

1.《深入理解计算机系统》第七章链接

动态链接库和静态链接库的相互包含问题及实现_第1张图片

动态链接库和静态链接库的相互包含问题及实现_第2张图片

2.《程序员的自我修养》第4章 静态链接和第7章 动态链接

3. http://blog.jobbole.com/86852/

目的

为了封装代码,简化接口,我们要把已有应用代码封装为动态链接库,应用代码又调用了其他库的文件,

为了减化编译配置,我们希望动态库直接调用其他库,固测试以下四种情况(含测试结论):

  1. 动态库包含静态库【编译test(main)时只需要libsecond.so,运行test(main)时只需要libsecond.so】
  2. 静态库包含静态库【编译test(main)时需要libfirst.a和libsecond.a,运行test(main)时不需要库】
  3. 动态库包含动态库【编译test(main)时需要libsecond.so,运行test(main)时需要libfirst.so和libsecond.so】
  4. 静态库包含动态库【编译test(main)时需要libfirst.so和libsecond.a,运行test(main)时需要libfirst.so】

静态接库本身不包含链接信息,在运行可执行程序时不需要静态库

动态链接库本身包含链接信息(U符号,不含T符号),在运行可执行程序时需要动态库(T符号)

环境

ubuntu 16.04 64位

gcc(glibc 64位+32位)

代码

调用关系,以下代码尽量简单明了,只为探索静态连接库和动态链接库的调用关系

动态链接库和静态链接库的相互包含问题及实现_第3张图片

first.h

#ifndef __FIRST_H_
#define __FIRST_H_

#include

void first();

#endif 

first.c

#include"first.h"

void first()
{
    printf("This is first!\n");
}

second.h

#ifndef __SECOND_H_
#define __SECOND_H_

#include

void second();

#endif 

second.c

#include"first.h"
#include"second.h"
void second()
{
    printf("This is second!\n");
    first();
}

test.c

#include"second.h"
int main()
{
    second();
    return 0;
}

实验

1. 动态库包含静态库

====================dynamic with static==========================test_ds only depends on libsecond.so
for 32bits linux we don't need -m32
for 64bits linux we need -m32

如果没有-m32 会产生错误:

relocation R_X86_64_32 against `.rodata' can not be used when making a shared object;

https://blog.csdn.net/bailyzheng/article/details/17613435

因为生成静态库时没有加 -fPIC 选项。,需要在生成静态库时加上-fPIC
=================================================================
gcc -m32 -c first.c
【生成】=>first.o

ar -crv libfirst.a first.o
=>libfirst.a
gcc second.c -m32 -fPIC -shared -o libsecond.so -L. -lfirst
=>libsecond.so


sudo gedit /etc/ld.so.conf.d/test.conf
---input absolute path of the dir of libsecond.so
sudo ldconfig

gcc test.c -m32 -o test_ds -L. -lsecond
=>test

./test_ds
=>
This is second!
This is first!

***********************

gcc -fPIC -c first.c

ar -crv libfirst.a first.o
gcc second.c -fPIC -shared -o libsecond.so -L. -lfirst
gcc test.c -o test_ds -L. -lsecond

./test_ds

***********************

 

2. 静态库包含静态库

======================static with static===================test_ss runs standalone
gcc -c first.c
ar -crv libfirst.a first.o
gcc -c second.c -L. -lfirst
ar -crv libsecond.a second.o
gcc test.c -L. -lsecond -lfirst -o test_ss

./test_ss
=>
This is second!
This is first!

nm libfirst.a 

first.o:
0000000000000000 T first
                 U puts

nm libsecond.a 

second.o:
                 U first
                 U puts
0000000000000000 T second

gcc  test.c -L. -lsecond
./libsecond.a(second.o): In function `second':
second.c:(.text+0x14): undefined reference to `first'
collect2: error: ld returned 1 exit status

3. 动态库包含动态库

======================dynamic with dynamic===================test_dd depends on libfirst.so libsecond.so 

gcc first.c -shared -fPIC -o libfirst.so

[
file libfirst.so 
libfirst.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=6fe6c0444eb028ec73283d6016ed7ffb14e36238, not stripped
]

gcc second.c -shared -fPIC -o libsecond.so -L. -lfirst
gcc test.c -L. -lsecond -o test_dd

sudo gedit /etc/ld.so.conf.d/test.conf
---input absolute path of the dir of libsecond.so
sudo ldconfig

./test_dd
=>
This is second!
This is first!

nm libfirst.so 
0000000000201028 B __bss_start
0000000000201028 b completed.7594
                 w __cxa_finalize@@GLIBC_2.2.5
00000000000005a0 t deregister_tm_clones
0000000000000630 t __do_global_dtors_aux
0000000000200e08 t __do_global_dtors_aux_fini_array_entry
0000000000201020 d __dso_handle
0000000000200e18 d _DYNAMIC
0000000000201028 D _edata
0000000000201030 B _end
00000000000006b4 T _fini
00000000000006a0 T first
0000000000000670 t frame_dummy
0000000000200e00 t __frame_dummy_init_array_entry
0000000000000748 r __FRAME_END__
0000000000201000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
00000000000006cc r __GNU_EH_FRAME_HDR
0000000000000548 T _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000200e10 d __JCR_END__
0000000000200e10 d __JCR_LIST__
                 w _Jv_RegisterClasses
                 U puts@@GLIBC_2.2.5
00000000000005e0 t register_tm_clones
0000000000201028 d __TMC_END__

nm libsecond.so 
0000000000201030 B __bss_start
0000000000201030 b completed.7594
                 w __cxa_finalize@@GLIBC_2.2.5
00000000000005f0 t deregister_tm_clones
0000000000000680 t __do_global_dtors_aux
0000000000200df8 t __do_global_dtors_aux_fini_array_entry
0000000000201028 d __dso_handle
0000000000200e08 d _DYNAMIC
0000000000201030 D _edata
0000000000201038 B _end
0000000000000710 T _fini
                 U first
00000000000006c0 t frame_dummy
0000000000200df0 t __frame_dummy_init_array_entry
00000000000007a8 r __FRAME_END__
0000000000201000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
000000000000072c r __GNU_EH_FRAME_HDR
0000000000000588 T _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000200e00 d __JCR_END__
0000000000200e00 d __JCR_LIST__
                 w _Jv_RegisterClasses
                 U puts@@GLIBC_2.2.5
0000000000000630 t register_tm_clones
00000000000006f0 T second
0000000000201030 d __TMC_END__

 

4. 静态库包含动态库

======================static with dynamic===================test_sd depends  nothing

gcc first.c -shared -fPIC -o libfirst.so

gcc -c second.c -L. -lfirst
ar crv libsecond.a second.o

gcc test.c -L. -lsecond【该静态链接库不能懈怠动态链接库的信息】

./libsecond.a(second.o): In function `second':
second.c:(.text+0x14): undefined reference to `first'
collect2: error: ld returned 1 exit status

gcc test.c -L. -lsecond -lfirst -o test_sd【works】

=>test_sd

./test_sd

=>

This is second!

This is first!

你可能感兴趣的:(动态链接库和静态链接库的相互包含问题及实现)