动态加载动态库

来源:互联网 发布:ubuntu虚拟机网络设置 编辑:程序博客网 时间:2024/04/20 09:49

1:

libf1.so

#ifndef F1_HH_
#define F1_HH_

extern 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掉

view plaincopy to clipboardprint?
#include <stdio.h>  
#include <stdlib.h>  
#include <dlfcn.h>  
#include <signal.h>  
#include <iostream>  
#include <errno.h>  
#include "f1.h"  
 
int isreload = 0;  
 
void sig_show(int s)  
{  
    printf("catched signal: %d/n", s);  
    return;  
}  
 
void sig_reloadso(int s)  
{  
    printf("catched signal: %d/n", s);  
    isreload = 1;  
    printf("sigfunc isreload ? %d/n", isreload);  
    return;  
}  
 
int main(int argc, char *argv [])  
{  
    std::cout <<"main begin/n";  
 
    struct sigaction show;  
    show.sa_handler = &sig_show;  
    show.sa_flags = SA_NOMASK;  
    show.sa_restorer = 0;  
    if(sigaction(3, &show, 0) == -1)  
    {  
        printf("sigaction failed. errno: %d/n", errno);  
        return 0;  
    }  
 
 
    struct sigaction reload;  
    reload.sa_handler = &sig_reloadso;  
    reload.sa_flags = SA_NOMASK;  
    reload.sa_restorer = 0;  
    if(sigaction(4, &reload, 0) == -1)  
    {  
        printf("sigaction failed. errno: %d/n", errno);  
        return 0;  
    }  
 
 
    void *libf2;  
    int (*f2)(char *);  
 
    const static char * h = "hello";  
    char buf[200];  
 
    if((libf2 = dlopen("./libf2.so", RTLD_NOW | RTLD_GLOBAL)) != 0)  
    {  
        f2 = (int (*)(char *)) dlsym(libf2, "func2");  
        if(dlerror())  
        {  
            printf("error? %s/n", dlerror());  
        }  
    }  
    else 
    {  
        printf("can not open libf2.so/n");  
        return 0;  
    }  
 
    int i;  
 
    while(1)  
    {  
        printf("isreload ? %d/n", isreload);  
 
        if(isreload)    //test if need reload  
        {  
            dlclose(libf2);  
 
            if((libf2 = dlopen("./libf2.so", RTLD_LAZY | RTLD_GLOBAL)) != 0)  
            {  
                f2 = (int (*)(char *)) dlsym(libf2, "func2");  
                if(dlerror())  
                {  
                    printf("error? %s/n", dlerror());  
                    return 0;  
                }  
            }  
 
            isreload = 0;  
            printf("successfully reload libf2.so/n");  
        }  
 
        ++i;  
 
        sprintf(buf, "%s %d", h, i);      
 
        f2(buf);        //from f2  
 
        func1(buf);     //from f1  
 
        sleep(4);  
    }  
      
    return 0;  

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/aalbertini/archive/2010/09/09/5873277.aspx