Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5698341
  • 博文数量: 675
  • 博客积分: 20301
  • 博客等级: 上将
  • 技术积分: 7671
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-31 16:15
文章分类

全部博文(675)

文章存档

2012年(1)

2011年(20)

2010年(14)

2009年(63)

2008年(118)

2007年(141)

2006年(318)

分类: C/C++

2011-04-28 12:43:58

在工作中,我们常常使用so插件进行扩展,这里简单实现一个so管理器,并对常见问题进行一些说明。

动态链接库在linux下基本上以so形式存在,对于so的操作,大家都知道怎么搞,无非是dlopen,dlsym和dlclose这几个API。

so管理器需要注意的问题:
1. dlopen使用RTLD_NOW进行当场符号检查,避免运行后出现符号找不到等错误。
2. 注意符号名不要经过c++ name mangling处理,否则的话符号名就会发生变化,直接使用dlsym查不到。
3. 使用map对dlsym得到的符号进行管理,方便上层直接按照符号进行调用。

符号名处理:
1. 使用extern "C" {}包裹声明,或者是直接使用extern "C"进行函数声明,在函数实现中创建So类,类中包含各种handle函数。
2. 使用全局变量声明,全局变量不会进行C++ name mangling,可以使用一个全局的struct,struct内部设置一个成员变量为So类,其中包含各种handle。

全局声明类:

#include "TestSo.h"
#include "SoMgr.h"

so_handle_t so_handle =
{
    new TestSo()
};

extern "C" {
    //func declare

};


extern "C"声明类:

extern "C" AbstractSo * get_instance()
{
    AbstractSo * p_so = new TestSo();
    return p_so;
}


关于so的编译啥的,这里就不说了,没啥大问题。这里再说一下so解析之后的处理。

SoMgr定义:

#define MAX_SO_NUM 32
#define STR_GETINSTANCE_SYM "get_instance"
#define STR_SOHANDLE_SYM "so_handle"

typedef AbstractSo * (* getinstance_func_t)();

typedef struct _so_item_t
{
    char _name[MAX_SO_NAME_LEN];
    void *_handle;
    AbstractSo *_so;
    _so_item_t()
    {
        _name[0] = '\0';
        _handle = NULL;
        _so = NULL;
    }
} so_item_t;

typedef struct _so_handle_t
{
    AbstractSo *so;
} so_handle_t;

class SoMgr
{
public:
    SoMgr(void);
    ~SoMgr(void);

    int LoadSoFromGetInstance(const char *dir_name, const char *so_name);
    int LoadSoFromDeclare(const char *dir_name, const char *so_name);
    AbstractSo *FindSo(const char *so_name);
private:

    so_item_t _so_items[MAX_SO_NUM];
    int _so_num;
};


对于编译,只有一点需要注意rdynamic。
-rdynamic 
Pass the flag ‘-export-dynamic’ to the ELF linker, on targets that support 
it. This instructs the linker to add all symbols, not only used ones, to the 
dynamic symbol table. This option is needed for some uses of dlopen or to 
allow obtaining backtraces from within a program.

选项 -rdynamic 用来通知链接器将所有符号添加到动态符号表中 
(目的是能够通过使用 dlopen 来实现向后跟踪)

最后是之前写的一个简单的示例代码。
文件:so.tar.gz
大小:2KB
下载:下载
阅读(2587) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~