日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

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

發布時間:2023/12/20 linux 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ctk编译linux,CTK插件框架学习5-插件间通信(Netlink实现热拔插监控) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本章來寫一個插件,插件功能為通過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实现热拔插监控)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。