dlopen系列函數


包含的頭文件:

#include <dlfcn.h>

使用的函數有以下4個:

1) void * dlopen( const char * pathname, int mode)
參數pathname: 動態庫so名稱

參數mode 打開方式,有以下選項

  RTLD_DEEPBIND -- 動態庫里的函數優先調用本動態庫的符號,優先級甚至高於LD_PRELOAD

  RTLD_LAZY -- 等有需要時才解析出符號,所以如果有未定義的符號,在沒調用之前也不執行解析
     RTLD_NOW -- 在dlopen返回前,解析出所有的未定義符號,如果解析不出來,返回NULL
     RTLD_GLOBAL 動態庫中符號表全局打開,因此符號可被其后打開的其它庫重定位

     RTLD_LOCAL  與RTLD_GLOBAL作用相反,動態庫中符號表非全局打開,定義的符號不能被其后打開的其它庫重定位

返回值:
  打開錯誤返回NULL
  成功,返回庫引用

2) void* dlsym(void* handle,const char* symbol)

參數handle: 動態庫應用或者RTLD_NEXT(在當前庫之后load進來的動態庫中尋找第一次出現的符號)

參數symbol: 符號名稱

返回值:符號函數指針

3) int dlclose (void *handle)

關閉指定句柄的動態鏈接庫

4) char* dlerror();

返回值:返回加載失敗的報錯信息

 

 

實例:

plugin.h頭文件中定義接口

#ifndef __PLUGIN_H__
#define __PLUGIN_H__
#include "stdio.h"
class IPlugin
{
public:
  virtual void print()=0;

};
#endif

main.cpp

#include "plugin.h"
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
typedef IPlugin* (*func)();
int main()
{
    
    void* handle = dlopen("/home/hongrui/work/dlopen/libplugin.so", RTLD_NOW);
    
    if (!handle)
    {
        printf("dlopen:%s\n",dlerror());
        return -1;
    }
    func getInterface = (func)dlsym(handle, "getInterface");
    if (getInterface == NULL)
    {
        printf("dlsym:%s\n", dlerror());
        return -1;
    }
    IPlugin* plugin =  getInterface();
    plugin->print();
   dlclose(handle);
return 0; }

編譯main.cpp 生成可執行文件

  g++ main.cpp -o main -ldl

plugin.cpp是動態庫cpp

#include "plugin.h"
#include "stdio.h"
class CPlugin : public IPlugin
{
public:
    CPlugin() {}
    virtual ~CPlugin(){}
    virtual void print()
    {
        printf("this is plugin\n");
    }
};

extern "C" __attribute__ ((visibility("default"))) IPlugin* getInterface()
{
    return new CPlugin;
}

編譯plguin.cpp生成動態庫libplugin.so

  

g++ -fvisibility=hidden -fpic -shared  plugin.cpp -o libplugin.so -ldl

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM