ctk编译linux,CTK插件框架学习5-插件间通信(Netlink实现热拔插监控)[通俗易懂]

ctk编译linux,CTK插件框架学习5-插件间通信(Netlink实现热拔插监控)[通俗易懂]本章来写一个插件,插件功能为通过NETLINK读取linux系统中的hotplug信息,比如usb、SD卡、磁盘等设备的插拔事件产生的信息,将读到的信息通过插件间通信的方式发出。1.eventadmin库编译CTKPluginFramework下插件间通信是通过事件管理机制实现的,其代码位于CTK/Libs/PluginFramework/service/event目录下,使能事件管理机制,…

大家好,又见面了,我是你们的朋友全栈君。

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

1. eventadmin库编译

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

686bf28e3b97480483f32841b6a6793a.png

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

6190768adcd8409bee9c0660708113bc.png

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平台运行下示例,测试插件运行情况。

e21d811e04f2fa968029fb0ba6ec38aa.png

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/139603.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Eclipse程序员要掌握的常用快捷键建议收藏

    判断一个人的编程水平,就看他用键盘多,还是鼠标多。用键盘一是为了输入代码(当然了,也包括注释),再有就是熟练使用快捷键。所以在网上找了一下,自己也总结了些用得比较多的,和大家一起分享一下。Ctrl+K

    2021年12月20日
    61
  • linux定时执行shell脚本「建议收藏」

    linux定时执行shell脚本「建议收藏」写一个shell脚本,定时执行简单示例很多时候我们有希望服务器定时去运行一个脚本来触发一个操作,比如说定时去备份服务器数据、数据库数据等不适合人工经常做的一些操作这里简单说下 Shell俗称壳,类似于DOS下的command和后来的cmd.exe。它接收用户命令,然后调用相应的应用程序。作为命令语言,它交互式解释和执行用户输入的命令或者自动地解释和执行预先设定好的一连串的命令;作为程…

    2025年9月3日
    5
  • css画圆弧_css圆角样式

    css画圆弧_css圆角样式CSS3是样式表(stylesheet)语言的最新版本,它的一大优点就是支持圆角。网页设计大师NicholasZakas的最新文章,清晰易懂地解释了CSS3圆角的各个方面,非常值得学习。以下就是我翻译的中文版。=========================================CSS3圆角详解作者:NicholasZakas译者:阮一峰发表日期:2010年12月8日一、CSS3…

    2025年7月25日
    2
  • fork join原理_典型相关分析

    fork join原理_典型相关分析privateForkJoinPool(intparallelism,ForkJoinWorkerThreadFactoryfactory,UncaughtExceptionHandlerhandler,intmode,StringworkerNamePrefix)fo…

    2022年9月20日
    3
  • Windows下cmd进入MySql的命令界面

    Windows下cmd进入MySql的命令界面####win+R快捷键打开运行,输入cmd,进入cmd若未将MySql加入环境变量,切换到mysql的安装目录下的bin目录;若已加入环境变量,则不必切换目录。输入主机名、数据库名、密码mysql-hlocalhost-uroot-p输入数据库密码

    2022年6月4日
    29
  • 怎么完全卸载赛门铁克_如何干净彻底卸载诺顿?

    怎么完全卸载赛门铁克_如何干净彻底卸载诺顿?诺顿有那么难卸载吗?我来教你如何彻底卸载诺顿!本方法跟重装的新系统差不多,没痕迹!很多朋友都遇到过无法卸载诺顿的问题,其实这是有原因的,因為它和操作系统高度整合,所以很多文件会直接注册到系统中,所以比起一般软件来是难点,但这样可以更好的保护您的系统安全。通过以下的方法可以完全卸载掉诺顿,可以顺利的安装诺顿新版本或者其它的杀毒软件。1.单击【开始】-【控制面板】,打开控制面板窗口,单击【添加删除程…

    2022年6月3日
    45

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号