linux类动态库,Linux动态库(一)

article/2025/10/25 6:47:03

起因

博主在以Linux下做开发。在软件需求中,需要动态库带来的灵活性。

比如说博主主导的智能主机的开发。它需要支持很多种类的设备控制,如普通的开关灯、RGB灯、窗帘、百叶窗等等。我们将这些设备抽象成Device类,具体的设备就从这个类上派生出来。每支持一个新设备就派生一个Device的子类进行具体能力的实现。如下:

80794499_1.png

如果我们在代码里将其写死。那么,将来我们每新添一个设备,我们都得更换整个应用程序。升级程序有风险,而且在升级过程中主机是会停止服务的。

那么,能不能在不停止应用程序的情况下直接支持新的设备的呢?我想是能的,用动态库实现的插件思想来做。当主机发现一个种类的设备,比如:门锁。主机之前并不认识,它便会拿着设备的model_id去向服务器请求其“驱动”。而这个驱动,则是该设备从Device派生的类DoorlockDevice的动态库文件 doorlock_device.so。主机将该动态库加载进来,并实例化其DoorlockDevice对象。于是,主机就可以正常控制门锁了。

这样做除了灵活以外,还有另一个优点:通常用户的智能家居系统中只有两三种设备,如果将死在代码里或者静态链接。主机程序在加载的时候会将100多个设备代码加载到内存中运行。这对于内存匮乏的嵌入式系统而言,这是莫大的浪费。如果采用动态库加载方式,主机程序不需要在启动的时候将所有的设备驱动加载到内存运行,而是按需加载。如此可以大大地节省内存开销。

于是,我一定要好好研究一下动态库加载与插件模式。

正题

好了,回归正题。下面是一个非常简单的例子,看看是如何实现的:

文件组织结构:

.

├── main.cpp

├── Makefile

└── plugins

├── device.cpp

├── device.h

├── devices

│   ├── rgb_device.cpp

│   ├── rgb_device.h

│   ├── switch_device.cpp

│   └── switch_device.h

└── Makefile

plugins/device.{h,cpp} 定义了设备的接口:

plugins/device.h

#ifndefDEVICE_H_20160508

#defineDEVICE_H_20160508

class Device {

public:

Device();

virtual ~Device();

public:

virtualvoidwork()= 0;

};

typedefDevice*create_func_t();

#endif//DEVICE_H_20160508

plugins/device.cpp

#include"device.h"

#include

using namespace std;

Device::Device() {

cout <

}

Device::~Device() {

cout <

}

定义的比较简单,就一个方法:work()

plugins/devices/ 目录下为Device的两个派生类:

RGBDevice类

#ifndefRGB_DEVICE_H_20160508

#defineRGB_DEVICE_H_20160508

#include"../device.h"

class RGBDevice: public Device {

public:

virtualvoidwork();

};

#endif//RGB_DEVICE_H_20160508

#include"rgb_device.h"

#include

using namespace std;

extern "C" Device*create(){

return new RGBDevice;

}

void RGBDevice::work() {

cout <

}

SwitchDevice类

#ifndefSWITCH_DEVICE_H_20160508

#defineSWITCH_DEVICE_H_20160508

#include"../device.h"

class SwitchDevice: public Device {

public:

virtualvoidwork();

};

#endif//SWITCH_DEVICE_H_20160508

#include"switch_device.h"

#include

using namespace std;

extern "C" Device*create(){

return new SwitchDevice;

}

void SwitchDevice::work() {

cout <

}

上面两个类的cpp里,我们都定义了一个create() 函数。它是用来创建一个对应的对象的。对于动态库里的对象,我们不能用new来创建。因为在编译main程序时,编译器根本就不知道如果new RGBDevice。

我们也不能提前在编译main程序时包含rgb_device.h(我们那时可能就不知道会有这个一个类)。综上,我们需要一个动态库内部指定的函数来创建。

plugins/Makefile的内容如下:

CFLAGS+=-shared -fPIC

CXXFLAGS+=$(CFLAGS)

all: librgb_device.so libswitch_device.so

librgb_device.so: devices/rgb_device.cpp device.cpp

$(CXX) $(CXXFLAGS) -o $@ $^

libswitch_device.so: devices/switch_device.cpp device.cpp

$(CXX) $(CXXFLAGS) -o $@ $^

clean:

-rm -f lib*.so

博主不太精于写Makefile,只能写成这样了。见笑了~

大致是这样的,每个派生类都要单独编译成一个libxxxx.so文件。如rgb_device,编译命令是:g++ -shared -o librgb_device.so -fPIC device/rgb_device.cpp device.cpp

为什么要加device.cpp ?因为RGBDevice继承于Device,而Device有自己的方法。如果编译时不加device.cpp,那么RGBDevice在链接时,不知道该怎么执行继承于Device的成员函数了。

好了,在plugins/下make一下,正常情况下,两个动态库就生成了。

下面看看main中如何加载动态库:

main.cpp

#include

#include

#include"device.h"

using namespace std;

intmain(){

cout <

void *handle = dlopen("./plugins/libswitch_device.so", RTLD_NOW);

if (handle == NULL) {

cerr <

return 0;

}

create_func_t *func = (create_func_t*)dlsym(handle, "create");

if (func != NULL) {

Device *d = (*func)();

if (d != NULL) {

d->work();

delete d;

} else

cerr <

}

dlclose(handle);

handle = NULL;

cout <

return 0;

}

Makefile

all: test

make -C plugins all

test: main.cpp

$(CXX) -o $@ $^ -I./plugins/ -ldl

clean:

make -C plugins clean

-rm test

注意:在链接main时,一定要添加 -ldl,否则不能支持dlopen, dlsym, dlclose 函数。

make 之后,运行结果:

start

Device construct

SwitchDevice work

Device destruct

done

dlopen("./plugins/libswitch_device.so", RTLD_NOW)

换成:

dlopen("./plugins/librgb_device.so", RTLD_NOW)

后再运行,结果是:

start

Device construct

RGB work

Device destruct

done

可见动态的效果了。如果我们将动态库名写在配置文件里。那么,只要修改一下配置文件,那么运行的效果就不同了。

这只是实现上面我的设想的第一步。后面再研究动态库的插件。

下次见!


http://chatgpt.dhexx.cn/article/I1ubA5ve.shtml

相关文章

OpenFlow Switch

The picture of OpenFlow Switch openflow 架构分为2层&#xff0c;一个是控制器层&#xff0c;一个是switch 层。中间是由openflow protocal进行连接的&#xff0c;负责传输指令与数据。switch分为3大块&#xff0c;第一是openflow channe&#xff0c;他是负责向控制器传输数据…

【博客450】OpenFlow学习

OpenFlow OpenFlow协议规范定义了OpenFlow交换机、流表、OpenFlow通道以及OpenFlow交换协议。 OpenFlow是第一个开放的南向接口协议&#xff0c;也是目前最流行的南向协议。它提出了控制与转发分离的架构&#xff0c;规定了SDN转发设备的基本组件和功能要求&#xff0c;以及与控…

OpenFlow交换机【ACM SIGCOMM顶会论文笔记】

目录 写在前面的话OpenFlow交换机基本思想与工作原理专用OpenFlow交换机&#xff08;Dedicated OpenFlow switches&#xff09; 启用OpenFlow的交换机&#xff08;OpenFlow-enabled switches&#xff09;其他功能&#xff08;Additional features&#xff09;控制器&#xff08…

关于ns-3中安装openflow的问题,解决openflow not found

官网 官网里面并没有明确的描述&#xff0c;这里结合自己的安装过程讲解一下 首先下载源码&#xff0c;记住这一步最好在ns-3目录下&#xff0c;就是运行waf命名的目录 $ hg clone http://code.nsnam.org/jpelkey3/openflow $ cd openflow进行编译&#xff0c;会提示缺少文件…

OpenFlow基础入门知识

本文进行讨论的是OpenFlow 1.0和OpenFlow 1.3的基本知识 Overview&#xff1a; Openflow 1.0&#xff1a; 安全通道单张流表ipv4 Openflow 1.3&#xff1a; 安全通道多级流表&#xff08;流水线pipeline&#xff09;组表测量表ipv6..... 流&#xff08;flow&#xff09; …

Openflow流表学习

Openflow流表学习 OpenFlow是一种新型的网络协议&#xff0c;它是控制器和交换机之间的标准协议。自2009年底发布1.0版本后&#xff0c;OpenFlow协议又经历了1.1、1.2、1.3及1.4版本的演进过程&#xff0c;目前使用和支持最多的是1.0和1.3版本。 OpenFlow1.3在1.0版的基础上进…

SDN与OPENFLOW 简介

本文对Openflow的发展、规范、应用和SDN的提出及相关应用做出较为客观全面的介绍。笔者希望通过本文对OpenFlow/SDN做一个初步介绍&#xff0c;以期帮助大家能够进一步深入了解和学习OpenFlow/SDN。 序言&#xff1a;从网络虚拟化说起 云计算的发展&#xff0c;是以虚拟化技术…

OpenFlow协议分析

实验环境&#xff1a;CentOS OpenDayLight-Carbon mininet WireShark 本实验通过wireshark抓包分析openflow1.3协议的各种报文与字段。 抓包 首先安装好实验所需的软件&#xff0c;这里不多赘述&#xff0c;需要的可以点击查看&#xff1a;mininet多方法安装&#xff0c;控制…

openflow简介

openflow交换机包含一些流表&#xff0c;流表负责具体包查找和转发 控制器通过of协议对流表查询和管理 一、流表 流表组成&#xff1a; 包头域、活动计数器、0个或多个执行行动 包头域&#xff1a; 计数器&#xff1a; 可以针对每张表、每个流、每个端口、每个队列来维护。…

SDN-OpenFlow1.0协议分析

目录 OpenFlow1.0代码 OpenFlow交换机流表 包头域 计数器 行动 流表匹配 OpenFlow消息 OpenFlow消息格式 对称消息 建立OpenFlow连接&#xff08;OFPT_HELLO消息&#xff09; 报告错误&#xff08;OFPT_ERROR消息&#xff09; 获取交换机特性信息&#xff08;Featu…

OpenFlow概述

OpenFlow简介 通俗的讲&#xff0c;OpenFlow是使用类似于API进程配置网络交换机的协议。OpenFlow的思路很简单&#xff0c;网络设备维护一个FlowTable并且只按照FlowTable进行转发&#xff0c;FlowTable本身的生成、维护、下发完全由外置的Controller来实现&#xff0c;注意这里…

OpenFlow了解

openflow的核心思想是将所有的协议都抽象出来&#xff0c;抽象成公共的flow概念。协议抽象&#xff1a;数据&#xff0c;函数&#xff08;对数据的处理方式&#xff09;&#xff0c;逻辑&#xff08;数据与处理的对应关系&#xff0c;函数之间的交互行为与时序&#xff09; pu…

OpenFlow交换机概述

1 交换机组成 OpenFlow交换机包括一个或多个流表和一个组表&#xff0c;执行分组查找和转发&#xff0c;和到一个外部控制器OpenFlow的信道。 控制器使用OpenFlow的协议&#xff0c;可添加、更新和删除流表中表项&#xff0c;既主动或被动响应数据包。 每个流表项包含匹配字段&…

openflow阅读感悟

一、背景 随着网络的快速发展和普及&#xff0c;设备和协议的复杂性导致了网络实验的困难。当时&#xff0c;几乎没有实际方法可以在足够现实的环境中尝试新的网络协议&#xff0c;来自网络学术、产业界的大多数新想法都未经试用和测试。因此&#xff0c;人们普遍认为网络基础设…

OpenFlow概念

OpenFlow是一种网络通信协议&#xff0c;应用于SDN架构中控制器和转发器之间的通信。软件定义网络SDN的一个核心思想就是“转发、控制分离”&#xff0c;要实现转、控分离&#xff0c;就需要在控制器与转发器之间建立一个通信接口标准&#xff0c;允许控制器直接访问和控制转发…

OpenFlow总结

OpenFlow总结 OpenFlow体系结构OpenFlow端口1.1、物理端口1.2、逻辑端口1.3、预定端口&#xff08;OpenFlow1.5中文版&#xff09; OpenFlow流表&#xff08;FlowTable&#xff09;2.1、概念2.2、流表结构 OpenFlow通信通道3.1、消息类型3.2 、消息交换 OpenFlow体系结构 Open…

Openflow

1.Openflow是啥 OpenFlow是第一个开放的南向接口协议&#xff0c;也是目前最流行的南向协议。 它提出了控制与转发分离的架构&#xff0c;规定了SDN转发设备的基本组件和功能要求&#xff0c;以及与控制器通信的协议。 2.OpenFlow组件 2.1. OpenFlow交换协议 2.2 OpenFlow网…

[学习笔记]OpenFlow概述(1)

个人学习笔记&#xff0c;出问题请指出下。摘取《图解OpenFLow》 Openflow协议是由斯坦福大学提出&#xff0c;最初的出发点是为了更加轻松地构建用于研究的网络。 Openflow的初期设计思想&#xff1a;无需设计新的硬件&#xff0c;只对现有硬件更新其软件。因此&#xff0c;O…

OpenFlow 协议详解(干货)

OpenFlow是一种新型的网络协议&#xff0c;它是控制器和交换机之间的标准协议。自2009年底发布1.0版本后&#xff0c;OpenFlow协议又经历了1.1、1.2、1.3及1.4版本的演进过程&#xff0c;目前使用和支持最多的是1.0和1.3版本。OpenFlow1.3在1.0版的基础上进一步优化及升级&…

OpenFlow概念学习

前言 OpenFlow交换机将原来完全由交换机/路由器控制的报文转发过程转化为由OpenFlow交换机和控制服务器来共同完成&#xff0c;目的交换机要通过of协议&#xff08;OpenFlow Protocol&#xff09;经安全通道&#xff08;Secure Channel&#xff09;连接到外部控制器&#xff08…