C++加载动态库的形式来实现封装

目录结构

└── test
    ├── CMakeLists.txt
    ├── base.h                            //设置接口
    ├── drive.cpp                        //具体实现
    └── main.cpp                        //test

CMakeLists.txt

cmake_minimum_required (VERSION 2.8)
project (test)

set(CMAKE_CXX_STANDARD 11)

include_directories(./)

add_library(drive SHARED drive.cpp) #将实现添加为动态库
add_executable(test main.cpp) #将test生成可执行
target_link_libraries(test ${CMAKE_DL_LIBS}) #链接dl库

base.h

#ifndef BASE_H
#define BASE_H
#include <iostream>
#include <memory>
#include <dlfcn.h>

using namespace std;

 //宏用在drive.cpp中生成产生子类对象的函数
#define USE_MAPFUSION_PLUGIN(C) extern "C"{\
    shared_ptr<base> createInstance(){return shared_ptr<base>(new C());}}     


class base;
typedef shared_ptr<base> (*funcCreatClass)();

class base {
public:
    virtual void print() {cout << "base" << endl;}

    static shared_ptr<base> create(const string& plugin) {
        int realFlags = RTLD_LAZY|RTLD_GLOBAL;
        void* handle = dlopen(plugin.c_str(), realFlags);//打开库
        if (!handle) {
            const char* err = dlerror();
            cerr << "Can not open file " << plugin << "since " << err << endl;
            return shared_ptr<base>();
        }
        funcCreatClass createFunc = (funcCreatClass)dlsym(handle, "createInstance");  //加载库中生成子类对象的函数
        if(!createFunc) return shared_ptr<base>();
        else return createFunc();
    }
};
#endif // BASE_H

drive.cpp

#include "base.h"

using namespace std;

class drive : public base {
public:
    virtual void print() {cout << "drive" << endl;}
};

USE_MAPFUSION_PLUGIN(drive)                                            //展开base.h中的宏来生成产生子类对象的函数


main.cpp

#include "base.h"

using namespace std;

int main(int argc, char *argv[])
{
    shared_ptr<base> a = base::create("libdrive.so");
    a->print();
}

运行结果

$ mkdir build
$ cd build
$ camke ..
$ make 
$ ./test
///输出
//drive
posted @ 2018-12-06 15:37  narjaja  阅读(866)  评论(0编辑  收藏  举报