linux动态加载so库文件


1:

libf1.so

 

#ifndef F1_HH_
#define F1_HH_

extern “C” int func1(char *p);
#endif

 

#include <iostream>
using namespace std;

#ifdef __cplusplus

extern "C" {

#endif

int func1(char *p)
{
   if(p)
   {
        std::cout <<"func1: " ;
        std::cout <<p << endl;
   }
   return 1;
}

 

#ifdef __cplusplus

}

#endif

 

libf2.so

类似, 只是输出不同

 

2: 编译so

g++ f1.cpp -shared -fPIC -g -o libf1.so

g++ f2.cpp -shared -fPIC -g -o libf2.so

 

 

3: 应用程序

注册信号、动态加载;收到信号后重新加载

几个注意点:

a)  so的编译

b)  #ifdef __cplusplus ; 防止找不到符号。 so的编译器与应用程序的编译器保持一致

c)  g++ -rdynamic -lf1 -g -o test main.cpp -ldl 编译应用程序。 -lf1的意思是动态链接libf1.so     -ldl是为了使得可以动态加载libf2.so

4)  应用程序使用的so必需是通过符号链接到真实的so文件; 可以直接加载so,但是这种情况下so不能被修改(覆盖),覆盖时会程序core掉

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <dlfcn.h>  
  4. #include <signal.h>  
  5. #include <iostream>  
  6. #include <errno.h>  
  7. #include "f1.h"  
  8.   
  9. int isreload = 0;  
  10.   
  11. void sig_show(int s)  
  12. {  
  13.     printf("catched signal: %d/n", s);  
  14.     return;  
  15. }  
  16.   
  17. void sig_reloadso(int s)  
  18. {  
  19.     printf("catched signal: %d/n", s);  
  20.     isreload = 1;  
  21.     printf("sigfunc isreload ? %d/n", isreload);  
  22.     return;  
  23. }  
  24.   
  25. int main(int argc, char *argv [])  
  26. {  
  27.     std::cout <<"main begin/n";  
  28.   
  29.     struct sigaction show;  
  30.     show.sa_handler = &sig_show;  
  31.     show.sa_flags = SA_NOMASK;  
  32.     show.sa_restorer = 0;  
  33.     if(sigaction(3, &show, 0) == -1)  
  34.     {  
  35.         printf("sigaction failed. errno: %d/n", errno);  
  36.         return 0;  
  37.     }  
  38.   
  39.   
  40.     struct sigaction reload;  
  41.     reload.sa_handler = &sig_reloadso;  
  42.     reload.sa_flags = SA_NOMASK;  
  43.     reload.sa_restorer = 0;  
  44.     if(sigaction(4, &reload, 0) == -1)  
  45.     {  
  46.         printf("sigaction failed. errno: %d/n", errno);  
  47.         return 0;  
  48.     }  
  49.   
  50.   
  51.     void *libf2;  
  52.     int (*f2)(char *);  
  53.   
  54.     const static char * h = "hello";  
  55.     char buf[200];  
  56.   
  57.     if((libf2 = dlopen("./libf2.so", RTLD_NOW | RTLD_GLOBAL)) != 0)  
  58.     {  
  59.         f2 = (int (*)(char *)) dlsym(libf2, "func2");  
  60.         if(dlerror())  
  61.         {  
  62.             printf("error? %s/n", dlerror());  
  63.         }  
  64.     }  
  65.     else  
  66.     {  
  67.         printf("can not open libf2.so/n");  
  68.         return 0;  
  69.     }  
  70.   
  71.     int i;  
  72.   
  73.     while(1)  
  74.     {  
  75.         printf("isreload ? %d/n", isreload);  
  76.   
  77.         if(isreload)    //test if need reload  
  78.         {  
  79.             dlclose(libf2);  
  80.   
  81.             if((libf2 = dlopen("./libf2.so", RTLD_LAZY | RTLD_GLOBAL)) != 0)  
  82.             {  
  83.                 f2 = (int (*)(char *)) dlsym(libf2, "func2");  
  84.                 if(dlerror())  
  85.                 {  
  86.                     printf("error? %s/n", dlerror());  
  87.                     return 0;  
  88.                 }  
  89.             }  
  90.   
  91.             isreload = 0;  
  92.             printf("successfully reload libf2.so/n");  
  93.         }  
  94.   
  95.         ++i;  
  96.   
  97.         sprintf(buf, "%s %d", h, i);      
  98.   
  99.         f2(buf);        //from f2  
  100.   
  101.         func1(buf);     //from f1  
  102.   
  103.         sleep(4);  
  104.     }  
  105.       
  106.     return 0;  
  107. }  




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值