C++在Linux下借助dlopen使用动态库

一、创作背景

由于在多方压力逼迫下,强制我开始制造学术垃圾。借此机会便把所用到的C++在Linux下如何真正意义上借助dlopen使用动态库,从而方便利用语言的多态特性。

二、核心基类

为了不丢脸,还是不使用自己的项目代码进行演示,做个简单的demo吧。
偷懒用HPP文件,定义声明实现怼一起啦~

#ifndef SHAPE_HPP
#define SHAPE_HPP

#include <iostream>

class Shape
{
public:
    Shape() {}
    virtual double getArea() const = 0;
    virtual double getPerim() const = 0;
    virtual void print() = 0;
    virtual void setShape(double edge1, double edge2, double angle) = 0;
    virtual ~Shape() {}
    static int count;
};

// the types of the class factories
typedef Shape *create_t();
typedef void destroy_t(Shape *);

void Shape::print()
{
    std::cout << "Area: " << getArea()
              << " Perim: " << getPerim() << std::endl;
}

#endif
三、继承类的实现

图形类继承出一个平行四边形类

#ifndef PARALLELOGRAM_CPP
#define PARALLELOGRAM_CPP

#include "shape.hpp"
#include <cmath>

class Parallelogram : public Shape
{
protected:
    double edge1;
    double edge2;
    double angle;

public:
    Parallelogram(double edge1 = 0, double edge2 = 0, double angle = 0);
    
    virtual void setShape(double edge1, double edge2, double angle);
    virtual double getPerim() const;
    virtual double getArea() const;
    virtual void print();
};

Parallelogram::Parallelogram(double edge1, double edge2, double angle)
{
    this->edge1 = edge1;
    this->edge2 = edge2;
    this->angle = angle;
}
void Parallelogram::setShape(double edge1, double edge2, double angle)
{
    this->edge1 = edge1;
    this->edge2 = edge2;
    this->angle = angle;
}
double Parallelogram::getArea() const
{
    return edge1 * edge2 * sin(angle);
}

double Parallelogram::getPerim() const
{
    return 2 * (edge1 + edge2);
}

void Parallelogram::print()
{
    std::cout << "Parallelogram: ";
    Shape::print();
}

// the class factories
extern "C" Shape *create()
{
    return new Parallelogram;
}
extern "C" void destroy(Shape *p)
{
    delete p;
}
#endif // PARALLELOGRAM_CPP
四、康一康main函数
#include "shape.hpp"
#include <iostream>
#include <dlfcn.h>
#include <cmath>

int main()
{
	void *handle = dlopen("./libparallelogram.so", RTLD_LAZY);
	if (!handle)
	{
		std::cout << "Cannot open library" << std::endl;
		return 1;
	}

	create_t *create = (create_t *)dlsym(handle, "create");
	destroy_t *destroy = (destroy_t *)dlsym(handle, "destroy");
	if (!create || !destroy)
	{
		std::cout << "Cannot find symbols" << std::endl;
		return 1;
	}

	Shape *p = create();
    p->setShape(1,2,M_PI/3);
	p->print();
	destroy(p);
	dlclose(handle);
	
	return 0;
}
五、编译运行

1)g++ parallelogram.cpp -fPIC -shared -o libparallelogram.so

2)g++ main.cpp -ldl

3)./a.out

六、结果展示

Parallelogram: Area: 1.73205 Perim: 6

七、总结分析

dlopen这个函数实际上如果不指定目录名./libparallelogram.so 这样子的话,会去本地的动态库目录内寻找。这时候就需要设置 LD_LIBRARY_PATH 环境变量。
此处带virtual关键字的函数,都是接口(interface) ,方便在装载不同动态库的时候,可实现同一接口但根据动态库不同来返回不同的信息内容(多态化)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值