本章来写一个插件,插件功能为通过NETLINK读取linux系统中的hotplug信息,比如usb、SD卡、磁盘等设备的插拔事件产生的信息,将读到的信息通过插件间通信的方式发出。

1. eventadmin库编译

CTK Plugin Framework下插件间通信是通过事件管理机制实现的,其代码位于CTK/Libs/PluginFramework/service/event目录下,使能事件管理机制,首先要在编译CTK的时候选择生成org.commontk.eventadmin库。如下图所示,打开cmake-gui,搜索plugin,然后把几个相关的库勾选上,重新编译CTK。

同样,参考上一篇博客,将编译生成的库文件,拷贝到Qt工程的"plugindepends/lib-平台名称"目录下,windows-x64-msvc平台下文件列表如下图所示。

2. eventadmin库环境配置

eventadmin插件属于ctk库自带的插件,可以通过如下方式启动。

ctkPluginFrameworkLauncher::addSearchPath(ctkPluginLibsPath, false); // 添加services插件目录

ctkPluginFrameworkLauncher::start("org.commontk.eventadmin"); // 启动插件框架,使能eventadmin service

需要先添加eventadmin插件库的所在目录,然后再启动。可以将liborg_commontk_eventadmin.dll文件拷贝到系统的库路径下,比如/usr/lib,然后在程序中修改路径,不过这样不利于代码做迁移。我们以在.pro文件中添加宏的形式来配置库路径,将库文件放在源码目录下。

首先,配置Plugindepends.pri文件,添加CTK_PLUGIN_LIBS宏,指向库路径,配置如下。

win32-msvc*{

# for windows visual studio 2015 x64 msvc compiler

CONFIG(debug, debug|release){

equals(QT_ARCH, x86_64): LIBS += -L$${PWD}/lib-windows-x64-msvc-debug -lCTKCore -lCTKPluginFramework

DEFINES += CTK_PLUGIN_LIBS=$${PWD}/lib-windows-x64-msvc-debug

}else{

equals(QT_ARCH, x86_64): LIBS += -L$${PWD}/lib-windows-x64-msvc-release -lCTKCore -lCTKPluginFramework

DEFINES += CTK_PLUGIN_LIBS=$${PWD}/lib-windows-x64-msvc-release

}

}

linux{

# for linux gcc x64 compiler

equals(QT_ARCH, x86_64){

LIBS += -L$$PWD/../plugindepends/lib-gcc-x64/ -lCTKCore -lCTKPluginFramework

DEFINES += CTK_PLUGIN_LIBS=$${PWD}/lib-gcc-x64

}

# for linux gcc arm64 compiler

equals(QT_ARCH, arm64){

LIBS += -L$$PWD/../plugindepends/lib-gcc-arm64/ -lCTKCore -lCTKPluginFramework

DEFINES += CTK_PLUGIN_LIBS=$${PWD}/lib-gcc-arm64

}

}

在源码中,可以通过宏转字符串的方式获取CTK_PLUGIN_LIBS指向的路径。

#define MACRO2STR(R) #R

#define STR_MACRO(R) MACRO2STR(R)

QString ctkPluginLibsPath = QString(STR_MACRO(CTK_PLUGIN_LIBS));

qDebug() << QString("add search path: %1").arg(ctkPluginLibsPath);

3. hotplug插件编写

通过拷贝的方式新建一个plugin-hotplug库,在plugin-hotplug库工程目录项,右键选择新建一个C++ class,取名为HotplugDetect,设置该类继承于QThread。在HotplugDetect类程序中,首先打开一个数据报socket,协议簇设置为AF_NETLINK,protocol为NETLINK_KOBJECT_UEVENT,代码如下。

const int buffersize = 2048;

int ret;

struct sockaddr_nl snl;

bzero(&snl, sizeof(struct sockaddr_nl));

snl.nl_family = AF_NETLINK;

snl.nl_pid = getpid();

snl.nl_groups = 1;

socket_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);

if (socket_fd == -1)

{

perror("socket");

}

setsockopt(socket_fd, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));

ret = bind(socket_fd, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl));

if (ret < 0)

{

perror("bind");

close(socket_fd);

}else{

qDebug() << "raw sock bind success.";

}

然后在QThread线程中,循环读取socket数据,然后将读出的信息简单过滤后以插件事件通信的方式发出去。发送事件信息代码如下,首先通过插件contex获取ctkEventAdmin服务,然后通过该服务发送一个ctkEvent事件,该事件中指定名称跟字典cdiry,字典中可以插入自定义数据。

QString recvStr;

recvLen = recv(socket_fd, &buf, sizeof(buf), 0);

if(recvLen > 0){

recvStr.sprintf("%s", buf);

...

ctkServiceReference csref = pcontex->getServiceReference();

ctkEventAdmin *eventAdmin = pcontex->getService(csref);

ctkDictionary cdiry;

cdiry.insert("plug_info", QString("[%1]%2").arg(QTime::currentTime().toString("mm:ss.zzz")).arg(recvStr));

ctkEvent event("testsop/hotplug", cdiry);

eventAdmin->postEvent(event);

}

4. 事件接收

事件接收程序可以单独写一个插件,也可以写到应用程序中。首先需要新建一个类,继承于ctkEventHandler。这里定义一个类Subscriber,定义代码如下。

#ifndef SUBSCRIBER_H

#define SUBSCRIBER_H

#include

#include

#include

class Subscriber : public QObject, public ctkEventHandler

{

Q_OBJECT

Q_INTERFACES(ctkEventHandler)

public:

Subscriber(ctkPluginContext *context);

// 将事件处理程序注册为服务

void registerServece();

// 处理事件

void handleEvent(const ctkEvent& event) Q_DECL_OVERRIDE;

private:

ctkPluginContext* pcontext;

};

#endif // SUBSCRIBER_H

注册事件处理服务时,要指定的事件名称需要与事件发送者指定的一致。

// 将事件处理程序注册为服务

void Subscriber::registerServece()

{

ctkDictionary cdiry;

cdiry.insert(ctkEventConstants::EVENT_TOPIC, "testsop/hotplug");

pcontext->registerService(this, cdiry);

}

事件处理函数handleEvent也比较简单,直接获取对应的属性值即可。

// 处理事件

void Subscriber::handleEvent(const ctkEvent &event)

{

QString infostr = event.getProperty("plug_info").toString();

qDebug() << QString("handleEvent_info: %1").arg(infostr);

}

5. 运行示例

这里以linux-x86_64平台运行下示例,测试插件运行情况。

ctk编译linux,CTK插件框架学习5-插件间通信(Netlink实现热拔插监控)相关推荐

  1. Java Plugin Framework (JPF) java插件框架学习

    2019独角兽企业重金招聘Python工程师标准>>> JPF (Java Plugin Framework) 是一个插件框架,类似Eclipse的插件系统,不过这个的依赖关系是使用 ...

  2. 插件框架之任务列表插件

    简单的任务列表也有存在的意义,意义就是多台电脑之间的同步,同步有多种方式,可以建立一个服务器,也可以将数据按照一定规则存储到某共有的存储器上.但我还希望这个插件具有向朋友发任务的一个功能,并且在任务完 ...

  3. linux高级编程基础系列:线程间通信

    线程间通信机制: 线程是一种轻量级的进程. 进程的通信机制主要包括无名管道.有名管道.消息队列.信号量.共享内存以及信号等.这些机制都是由linux内核来维护的,实现起来都比较复杂,而且占用大量的系统 ...

  4. 反编译linux内核 kmem,Volatility学习笔记一:使用手册

    0x00 概述 Volatility是一款开源内存取证框架,能够对导出的内存镜像进行分析,通过获取内核数据结构,使用插件获取内存的详细情况以及系统的运行状态. 特点: 开源:Python编写,易于和基 ...

  5. Linux图形显示DRM框架学习

    一.Direct Rendering Manager(DRM)是linux内核子系统,负责与显卡交互.DRM提供一组API,用户空间程序可以使用该API将命令和数据发送到GPU或者专用图形处理硬件(如 ...

  6. linux jedi-vim安装,python学习-vim插件安装

    centos7上自带python2.7,我们需要优化一下python环境.一.使用豆瓣源加速软件安装pip install -i   flask    #使用-i 选项 mkdir ~./pip &a ...

  7. 《LINUX设备驱动程序》学习之与硬件通信(并行接口)实例

    在学习这一节内容时,我根据书本写了一个并口驱动程序,然后用一个LED发光二极管.一个电阻以及一些导线和电脑主机的并口连接了一条回路,最后通过测试程序控制LED灯的开启.关闭,验证了并口驱动程序的正确性 ...

  8. QT多插件通信框架CTK编译记录

    目录 一  编译结果 二   部署配置 三  Log4Qt编译配置 四  参考链接 五  拓展资料 一  编译结果 参考链接有源码. 二   部署配置 ##CTK.pri# CTK install d ...

  9. Android 插件化原理 完胜360插件框架 技术实战

    性能优化 Android 性能优化 (一)APK高效瘦身 http://blog.csdn.net/whb20081815/article/details/70140063 Android 性能优化 ...

最新文章

  1. 管理距离 路由与交换_动态路由选择原理(距离矢量路由协议RIP)
  2. jQuery核心函数的使用总结
  3. 小程序mysql+php测试,分享微信小程序的一些常见辅助测试功能:chance
  4. pt-online-schema-change 在线修改表结构
  5. 布局中常见的居中问题
  6. 优质的程序员需为代码效率而呕心沥血
  7. sql replace函数_SQL REPLACE函数概述
  8. 如何为XAF设置默认属性值?
  9. 美年健康俞熔:创业者最重要的是锻造内心、熬过拐点 | 凌云时刻
  10. 黑苹果系统是服务器系统,黑苹果各种版本的说明 _ 黑苹果乐园
  11. 最新微信养号、使用、解封必看的注意事项
  12. 2022年瑞典经济发展研究报告
  13. 三位数的茎叶图怎么看_如何看懂茎叶图
  14. Linux内核之进程6: 深度睡眠
  15. 一个屌丝程序员的青春(二六五)
  16. ubuntu 20.04安装各类软件
  17. 京东零售大数据云原生架构实践
  18. C语言 队列(循环队列和链队初始化进出队等基本操作)
  19. Arduino录音时间延长_如何用arduino设计出可以语音播报的数字时钟
  20. zoj 3716 Ribbon Gymnastics【神奇的计算几何】

热门文章

  1. antd动态隐藏表格中的一列_有很多excel表格,如何快速合并到一张表格里?
  2. python asyncio future 多线程_深究Python中的asyncio库-线程池
  3. java实验1_Java程序实验1
  4. Python(2):基本数据类型
  5. 一个简单的if else优化
  6. SpringSecurity实现拦截未登录页面
  7. 支持向量机的近邻理解:图像二分类为例(1)
  8. 三维重建:***三维模型的网格细化
  9. 解决JavaOpenCV的内存问题
  10. Linux的前世今生