Linux下动态链接库调用


Linux下动态链接库调用  

Linux下的静态链接库,做起来比较容易,只要将目标文件用ar打包就可以,下面写一下动态链接库的制作和使用方法,完全是根据个人理解和经验总结,有不对的地方还请大家指正。

动态链接库的生成:

代码上与写静态链接库没什么区别,主要是在编译时,以两个文件举例:



centos 动态库容cpu linux 动态库调用_centos 动态库容cpu


/* 
   mylib.h 
   */ 
   
 
   void 
    Print();

 
   /* 
   mylib.c 
   */ 
   
 #include  
   < 
   stdio.h 
   > 
   
 #include  
   " 
   mylib.h 
   " 
   

 
   void 
    Print()
 {
     printf( 
   " 
   This is in mylib\n 
   " 
   );
 }



centos 动态库容cpu linux 动态库调用_centos 动态库容cpu



编译方法如下:

gcc -fpic -shared mylib.c -o mylib.so

此时将生成mylib.so动态链接库文件。

动态链接库在使用时,分为“隐式调用”和“显式调用”两种。

隐式调用,则与静态库的使用方法差不多,注意需要包含导出函数的头文件,即mylib.h:



centos 动态库容cpu linux 动态库调用_centos 动态库容cpu



#include  
   < 
   stdio.h 
   > 
   
 #include  
   " 
   mylib.h 
   " 
   

 
   int 
    main()
 {
     Print();
 }


centos 动态库容cpu linux 动态库调用_centos 动态库容cpu



编译方法:

gcc -o main main.c -L./ mylib.so

注意要加上动态链接库的搜索路径,否则编译器只会到系统路径中去寻找。

显式调用的方式,不必包含mylib.h,但是需要增加几个系统调用:



centos 动态库容cpu linux 动态库调用_centos 动态库容cpu



#include  
   < 
   stdio.h 
   > 
   
 #include  
   < 
   dlfcn.h 
   > 
     
   // 
    显式加载需要用到的头文件 
   
 
   
 
   int 
     main()
 {
      
   void 
     
   * 
   pdlHandle  
   = 
    dlopen( 
   " 
   ./mylib.so 
   " 
   , RTLD_LAZY);  
   // 
    RTLD_LAZY 延迟加载 
   
      
   if 
   (  
   pdlHandle == NULL 
    )
     {
         printf( 
   " 
   Load mylib failed!\n 
   " 
   )
          
   return 
     
   1 
   ;
     }

      
   void 
    ( 
   * 
   Print)()  
   = 
    dlsym(pdlHandle,  
   " 
   Print 
   " 
   );  
   // 
    定位动态链接库中的函数 
   
 
        
   if 
   (  
   ! 
   Print )
     {
         pszErr  
   = 
    dlerror();
         printf( 
   " 
   Find symbol failed!%s\n 
   " 
   , pszErr);
         dlclose(pdlHandle);
          
   return 
     
   1 
   ;
     }

     Print();  
   // 
    调用动态链接库中的函数 
   
 
   
     dlclose(pdlHandle);  
   // 
    系统动态链接库引用数减1 
   
 
   
      
   return 
     
   0 
   ;
 }




另外cpp的库在使用这种方式时要用extern “C”声明下,

对于cpp,类可以在函式中作为局部对象调用,如果想使用库中声明的类,则要以返回值的形式来产生了。



可以看到,显式调用的代码看上去要复杂很多,但是却比隐式调用要灵活,我们不必在编译时就确定要加载哪个动态链接库,可以在运行时再确定,甚至重新加载。

看一下显式调用的编译方式:

gcc -ldl -o main main.c

注意要添加-ldl选项,以使用显式调用相关的函数调用。