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

时间:2023-12-18 08:15:20

目录结构

└── 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