天天看點

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

繼續閱讀