zoukankan      html  css  js  c++  java
  • 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
    
  • 相关阅读:
    汪博士解读PMP考试
    ASP.NET编程实战宝典(光盘内容另行下载,地址见书封底)
    [模板]tarjan算法求SCC
    [POJ 3071]Football[概率DP]
    [数学]根式有理化[高中数学技巧]
    [平面几何]角格点问题
    [数学]对数均值不等式
    [模板][快速排序&归并排序]
    [POJ]P3126 Prime Path[BFS]
    每日一题_191219
  • 原文地址:https://www.cnblogs.com/narjaja/p/10077026.html
Copyright © 2011-2022 走看看