找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1770|回复: 0
打印 上一主题 下一主题
收起左侧

如何动态加载.so文件

[复制链接]
跳转到指定楼层
楼主
ID:107189 发表于 2016-3-5 19:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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;   
}  


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表