C++載入動態庫的形式來實現封裝
阿新 • • 發佈:2018-12-06
目錄結構
└── 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