鏈接與加載---2.dlopen共享庫

1. 
1.1 共享庫
有如下代碼共享庫與主函數中都有相同的add函數
  1. cong@msi:/work/test/ctest/5dlopen_1$ cat libtestadd/libadd.
  2. int add(int a, int b)
  3. {
  4.     return (a+b);
  5. }
編譯生成共享庫:
gcc -g -fPIC -O0   -c -o libadd.o libadd.c
gcc -fPIC -shared libadd.o -o libtestadd.so
1.2 主函數
  1. cong@msi:/work/test/ctest/5dlopen_1$ cat main.
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "libadd.h"
  6. int add(int a, int b)
  7. {
  8.     printf("main.c: add\n");
  9.     return 0;
  10. }
  11. int main (int argc, char *argv[])
  12. {
  13.     printf("add=%d\n",add(1,2));
  14.     return 0;
  15. }
gcc -g -O0 -I./libtestadd    -c -o main.o main.c
gcc main.o -o main -L./libtestadd/ -ltestadd  -Wl,-rpath,libtestadd
1.3 運行結果
  1. cong@msi:/work/test/ctest/5dlopen_1$ ./main 
  2. main.c: add                    -->發現調用的是主函數的add
  3. add=0
用ldd及readelf查看
  1. cong@msi:/work/test/ctest/5dlopen_1$ ldd main
  2.     linux-vdso.so.=> (0x00007ffd975d9000)           -->這兒根本就沒有去鏈接libtestadd.so
  3.     libc.so.=> /lib/x86_64-linux-gnu/libc.so.(0x00007f6ca45c9000)
  4.     /lib64/ld-linux-x86-64.so.(0x00007f6ca49b5000)
  5. cong@msi:/work/test/ctest/5dlopen_1$ 
  6. cong@msi:/work/test/ctest/5dlopen_1$ readelf -./main

  7. Dynamic section at offset 0xe18 contains 25 entries:
  8.   Tag Type Name/Value
  9.  0x0000000000000001 (NEEDED) Shared library: [libc.so.6]   -->需要的共享庫只有libc.so根本就沒有用libtestadd.so
  10.  0x000000000000000f (RPATH) Library rpath: [libtestadd]
  11.  0x000000000000000c (INIT) 0x400428
將main.c中的add函數注掉之後,再次用ldd及readelf查看:
  1. cong@msi:/work/test/ctest/5dlopen_1$ ldd main
  2.     linux-vdso.so.=> (0x00007ffd43f39000)
  3.     libtestadd.so => libtestadd/libtestadd.so (0x00007fd3bebd0000)     -->去掉main中的add纔會用到libtestadd.so這個共享庫
  4.     libc.so.=> /lib/x86_64-linux-gnu/libc.so.(0x00007fd3be7e6000)
  5.     /lib64/ld-linux-x86-64.so.(0x00007fd3bedd4000)
  6. cong@msi:/work/test/ctest/5dlopen_1$ 
  7. cong@msi:/work/test/ctest/5dlopen_1$ readelf -./main
  8. Dynamic section at offset 0xe08 contains 26 entries:
  9.   Tag Type Name/Value
  10.  0x0000000000000001 (NEEDED) Shared library: [libtestadd.so]           -->去掉main中的add纔會用到共享庫中的add
  11.  0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
  12.  0x000000000000000f (RPATH) Library rpath: [libtestadd]
  13.  0x000000000000000c (INIT) 0x400580
1.4 代碼下載
5dlopen_1.rar   (下載後改名爲5dlopen_1.tar.gz)

2. 運行時加載庫
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <dlfcn.h>
  5. int add(int a, int b)
  6. {
  7.     printf("add in main.c\n");
  8.     return (a+b);
  9. }
  10. #define TEST_LIB_PATH "./libtestadd/libtestadd.so"
  11. int main (int argc, char *argv[])
  12. {
  13.     int result;
  14.     void* dp = NULL;
  15.     int (*add_func)(int, int);
  16.     dp = dlopen(TEST_LIB_PATH, RTLD_LAZY );
  17.     if(dp==NULL)
  18.     {
  19.         printf("dlopen failed\n");
  20.         return 0;
  21.     }

  22.     add_func = dlsym(dp, "add");
  23.     result = add_func(3, 4);
  24.     printf("addr of add_func=%p\n", add_func);
  25.     printf("dlopen: add_func=%d\n", result);
  26.     dlclose(dp);

  27.     printf("add=%d\n",add(1,2));
  28.     return 0;
  29. }
2.3 運行結果
  1. cong@msi:/work/test/ctest/5dlopen$ ./main 
  2. addr of add_func=0x7f192e886675
  3. dlopen: add_func=7    -->運行了libtestadd.so中的add
  4. add in main.c
  5. add=3
用dlopen之後再次用ldd及readelf查看:
  1. cong@msi:/work/test/ctest/5dlopen$ ldd main
  2.     linux-vdso.so.=> (0x00007ffdea9f0000)
  3.     libdl.so.=> /lib/x86_64-linux-gnu/libdl.so.(0x00007f5d20aa9000)   -->需要用到libdl.so,但是自己的libtestadd.so沒有用到
  4.     libc.so.=> /lib/x86_64-linux-gnu/libc.so.(0x00007f5d206e4000)
  5.     /lib64/ld-linux-x86-64.so.(0x00007f5d20cd4000)
  6. cong@msi:/work/test/ctest/5dlopen$ readelf -./main

  7. Dynamic section at offset 0xe18 contains 25 entries:
  8.   Tag Type Name/Value
  9.  0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]    -->需要用到libdl.so,但是自己的libtestadd.so沒有用到
  10.  0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
  11.  0x000000000000000c (INIT) 0x400588
2.4 代碼下載
 5dlopen.rar
(下載後改名爲5dlopen.tar.gz)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章