Qt-共享内存QSharedMemory
相关资料:
https://blog.csdn.net/qq_33266987/article/details/60872001 QString 和 char* 之间的转换(以及QByteArray)
https://www.cnblogs.com/ybqjymy/p/12557703.html Qt QString转char[]数组
https://liang.blog.csdn.net/article/details/108894720 Qt 读写共享内存
https://blog.csdn.net/gdutlyp/article/details/50468677 Qt学习—qt共享内存的使用
https://download.csdn.net/download/zhujianqiangqq/19125137 代码包下载
代码实例:
.pro
1 QT += core gui 2 3 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 4 5 CONFIG += c++11 6 7 # The following define makes your compiler emit warnings if you use 8 # any Qt feature that has been marked deprecated (the exact warnings 9 # depend on your compiler). Please consult the documentation of the 10 # deprecated API in order to know how to port your code away from it. 11 DEFINES += QT_DEPRECATED_WARNINGS 12 13 # You can also make your code fail to compile if it uses deprecated APIs. 14 # In order to do so, uncomment the following line. 15 # You can also select to disable deprecated APIs only up to a certain version of Qt. 16 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 17 18 SOURCES += \ 19 main.cpp \ 20 mainwindow.cpp 21 22 HEADERS += \ 23 mainwindow.h 24 25 FORMS += \ 26 mainwindow.ui 27 28 # Default rules for deployment. 29 qnx: target.path = /tmp/$${TARGET}/bin 30 else: unix:!android: target.path = /opt/$${TARGET}/bin 31 !isEmpty(target.path): INSTALLS += target
main.cpp
1 #include "mainwindow.h" 2 3 #include <QApplication> 4 5 int main(int argc, char *argv[]) 6 { 7 QApplication a(argc, argv); 8 MainWindow w; 9 w.show(); 10 return a.exec(); 11 }
mainwindow.h
1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include <QMainWindow> 5 6 #include <QSharedMemory> 7 8 9 //测试使用的数据结构 10 typedef struct{ 11 int age; 12 char name[12]; 13 }DataInfo;//注意考虑内存对齐,尽量凑为8的倍数,不够的添加保留位 14 15 16 QT_BEGIN_NAMESPACE 17 namespace Ui { class MainWindow; } 18 QT_END_NAMESPACE 19 20 class MainWindow : public QMainWindow 21 { 22 Q_OBJECT 23 24 public: 25 MainWindow(QWidget *parent = nullptr); 26 ~MainWindow(); 27 28 private slots: 29 void on_pushButton_clicked(); 30 31 void on_pushButton_2_clicked(); 32 33 void on_pushButton_3_clicked(); 34 35 void on_pushButton_4_clicked(); 36 37 void on_pushButton_5_clicked(); 38 39 void on_pushButton_11_clicked(); 40 41 void on_pushButton_6_clicked(); 42 43 void on_pushButton_7_clicked(); 44 45 void on_pushButton_8_clicked(); 46 47 void on_pushButton_9_clicked(); 48 49 void on_pushButton_10_clicked(); 50 51 void on_pushButton_12_clicked(); 52 53 void on_pushButton_13_clicked(); 54 55 void on_pushButton_14_clicked(); 56 57 private: 58 Ui::MainWindow *ui; 59 60 QSharedMemory *m_pShareMemory; //定义共享内存实例指针 61 int m_nIndex = 0; 62 }; 63 #endif // MAINWINDOW_H
mainwindow.cpp
1 #include "mainwindow.h" 2 #include "ui_mainwindow.h" 3 4 MainWindow::MainWindow(QWidget *parent) 5 : QMainWindow(parent) 6 , ui(new Ui::MainWindow) 7 { 8 ui->setupUi(this); 9 } 10 11 MainWindow::~MainWindow() 12 { 13 delete ui; 14 } 15 16 //利用QSharedMemory类创建实例对象时,必须为该共享内存指定关键字(即为该共享内存起一个名字)。 17 //只有当共享内存被设置了关键字之后,才可以执行创建create)、关联attach()等操作。为共享内存指定关键字有 18 void MainWindow::on_pushButton_clicked() 19 { 20 m_pShareMemory = new QSharedMemory("QSharedMemoryExample", this); //构造实例对象 21 // m_pShareMemory->setKey("QSharedMemoryExample");// 也可以生成对象后给名称,咱们在这里不使用这个 22 } 23 24 // 为QSharedMemory类实例对象创建一个空间大小为size的共享内存,该内存空间默认的访问方式为可读可写。 25 // 共享内存创建成功返回true,否则返回false。QSharedMemory类定义一个枚举类变量AccessMode, 26 // 指定了两种共享内存的访问方式: 27 // QSharedMemory::ReadOnly 只读方式访问共享内存 28 // QSharedMemory::ReadWrite 读写方式访问共享内存 29 void MainWindow::on_pushButton_12_clicked() 30 { 31 m_pShareMemory->create(512, QSharedMemory::ReadWrite); 32 } 33 34 //将以关键字key命名的共享内存和当前程序进行关联,共享内存默认的访问方式为可读写。如果程序和共享内存关联成功, 35 //返回true,否则返回false。 36 void MainWindow::on_pushButton_2_clicked() 37 { 38 m_pShareMemory->attach(); 39 } 40 41 //解除共享内存和程序的关联,即调用该函数后,程序不可以再访问共享内存。如果该共享内存被多个程序实例所关联, 42 //当最后一个程序实例和共享内存解除关联后,该共享内存将由操作系统自动释放掉。分离操作成功, 43 //返回true。如果返回false,通常意味着该共享内存和程序分离失败,或者其他程序当前正在访问该共享内存,分离操作执行失败。 44 void MainWindow::on_pushButton_3_clicked() 45 { 46 m_pShareMemory->detach(); 47 } 48 49 //该函数用来判断程序(调用该函数的程序)是否和共享内存进行关联,是返回true,否返回false。 50 void MainWindow::on_pushButton_4_clicked() 51 { 52 ui->textEdit->append(QString::number(m_pShareMemory->isAttached())); 53 } 54 55 //Qt应用程序通过关键字来辨识共享内存。key ()函数用来获取共享内存的关键字,如果没有指定实例对象的关键字, 56 //或者共享内存的关键字是由nativeKey ()函数指定的话,则返回空。 57 void MainWindow::on_pushButton_5_clicked() 58 { 59 ui->textEdit->append(m_pShareMemory->key()); 60 } 61 62 //setKey () 函数用来为共享内存段设定关键字 ( 为共享内存命名 ) , 63 //如果参数 key 的值和构造函数或者之前指定的关键字相同的话,则该函数将不做任何操作,直接返回。 64 void MainWindow::on_pushButton_11_clicked() 65 { 66 m_pShareMemory->setKey(ui->lineEdit_2->text()); 67 } 68 69 void MainWindow::on_pushButton_6_clicked() 70 { 71 m_pShareMemory->lock(); 72 } 73 74 void MainWindow::on_pushButton_7_clicked() 75 { 76 m_pShareMemory->unlock(); 77 } 78 79 void MainWindow::on_pushButton_8_clicked() 80 { 81 //当共享内存出错时,调用该函数显示相应的错误代码。 82 //m_pShareMemory->error(); 83 //当共享内存出错时,调用该函数,以文本形式显示错误原因。 84 ui->textEdit->append(m_pShareMemory->errorString()); 85 } 86 87 //程序关联共享内存的前提下,调用该函数返回共享内存中数据的起始地址。如果没有关联共享内存,则返回0 88 void MainWindow::on_pushButton_9_clicked() 89 { 90 std::stringstream ss1; 91 ss1 << m_pShareMemory->data(); 92 std::string name = ss1.str(); 93 ui->textEdit->append(QString::fromStdString(name)); 94 } 95 96 //调用该函数将返回程序所关联的共享内存的大小(字节)。如果没有关联的共享内存,则返回0 97 void MainWindow::on_pushButton_10_clicked() 98 { 99 ui->textEdit->append(QString::number(m_pShareMemory->size())); 100 } 101 102 103 void MainWindow::on_pushButton_13_clicked() 104 { 105 DataInfo oInfo;// = {71, "zhangsan"}; 106 m_nIndex = m_nIndex + 1; 107 oInfo.age = m_nIndex; 108 // 109 char* ch; 110 QByteArray ba = ui->lineEdit->text().toLatin1(); 111 ch = ba.data(); 112 // 113 memcpy(oInfo.name, ch, 12); 114 m_pShareMemory->lock(); //锁定共享内存 115 m_pShareMemory->lock();//上锁 116 char *shm_addr = (char *)m_pShareMemory->data();//获取共享内存映射首地址 117 memcpy(shm_addr, &oInfo, sizeof(oInfo));//写入数据, 这里注意写入的数据长度不能超过共享内存的大小 118 m_pShareMemory->unlock();//解锁 119 } 120 121 void MainWindow::on_pushButton_14_clicked() 122 { 123 DataInfo oInfo = {0, ""}; 124 m_pShareMemory->lock();//加锁 125 memcpy(&oInfo, m_pShareMemory->constData(), sizeof(oInfo)); 126 m_pShareMemory->unlock();//解锁 127 QString sInfo = "age %1 name %2"; 128 sInfo = sInfo.arg(oInfo.age).arg(oInfo.name); 129 ui->lineEdit->setText(sInfo); 130 }
mainwindow.ui
1 <?xml version="1.0" encoding="UTF-8"?> 2 <ui version="4.0"> 3 <class>MainWindow</class> 4 <widget class="QMainWindow" name="MainWindow"> 5 <property name="geometry"> 6 <rect> 7 <x>0</x> 8 <y>0</y> 9 <width>747</width> 10 <height>444</height> 11 </rect> 12 </property> 13 <property name="windowTitle"> 14 <string>MainWindow</string> 15 </property> 16 <widget class="QWidget" name="centralwidget"> 17 <widget class="QPushButton" name="pushButton"> 18 <property name="geometry"> 19 <rect> 20 <x>550</x> 21 <y>10</y> 22 <width>75</width> 23 <height>23</height> 24 </rect> 25 </property> 26 <property name="text"> 27 <string>创建内存对象</string> 28 </property> 29 </widget> 30 <widget class="QPushButton" name="pushButton_2"> 31 <property name="geometry"> 32 <rect> 33 <x>550</x> 34 <y>70</y> 35 <width>75</width> 36 <height>23</height> 37 </rect> 38 </property> 39 <property name="text"> 40 <string>联接内存</string> 41 </property> 42 </widget> 43 <widget class="QPushButton" name="pushButton_3"> 44 <property name="geometry"> 45 <rect> 46 <x>550</x> 47 <y>100</y> 48 <width>75</width> 49 <height>23</height> 50 </rect> 51 </property> 52 <property name="text"> 53 <string>分离内存</string> 54 </property> 55 </widget> 56 <widget class="QPushButton" name="pushButton_4"> 57 <property name="geometry"> 58 <rect> 59 <x>484</x> 60 <y>140</y> 61 <width>141</width> 62 <height>23</height> 63 </rect> 64 </property> 65 <property name="text"> 66 <string>判断共享内存的关联状态</string> 67 </property> 68 </widget> 69 <widget class="QPushButton" name="pushButton_5"> 70 <property name="geometry"> 71 <rect> 72 <x>464</x> 73 <y>170</y> 74 <width>161</width> 75 <height>23</height> 76 </rect> 77 </property> 78 <property name="text"> 79 <string>获取共享内存的关键字</string> 80 </property> 81 </widget> 82 <widget class="QPushButton" name="pushButton_6"> 83 <property name="geometry"> 84 <rect> 85 <x>450</x> 86 <y>220</y> 87 <width>91</width> 88 <height>23</height> 89 </rect> 90 </property> 91 <property name="text"> 92 <string>锁定共享内存</string> 93 </property> 94 </widget> 95 <widget class="QPushButton" name="pushButton_7"> 96 <property name="geometry"> 97 <rect> 98 <x>544</x> 99 <y>220</y> 100 <width>91</width> 101 <height>23</height> 102 </rect> 103 </property> 104 <property name="text"> 105 <string>解锁共享内存</string> 106 </property> 107 </widget> 108 <widget class="QPushButton" name="pushButton_8"> 109 <property name="geometry"> 110 <rect> 111 <x>450</x> 112 <y>250</y> 113 <width>181</width> 114 <height>23</height> 115 </rect> 116 </property> 117 <property name="text"> 118 <string>错误原因</string> 119 </property> 120 </widget> 121 <widget class="QPushButton" name="pushButton_9"> 122 <property name="geometry"> 123 <rect> 124 <x>450</x> 125 <y>280</y> 126 <width>181</width> 127 <height>23</height> 128 </rect> 129 </property> 130 <property name="text"> 131 <string>获取共享内存的地址</string> 132 </property> 133 </widget> 134 <widget class="QPushButton" name="pushButton_10"> 135 <property name="geometry"> 136 <rect> 137 <x>450</x> 138 <y>310</y> 139 <width>181</width> 140 <height>23</height> 141 </rect> 142 </property> 143 <property name="text"> 144 <string>获取共享内存的大小</string> 145 </property> 146 </widget> 147 <widget class="QTextEdit" name="textEdit"> 148 <property name="geometry"> 149 <rect> 150 <x>10</x> 151 <y>10</y> 152 <width>411</width> 153 <height>291</height> 154 </rect> 155 </property> 156 </widget> 157 <widget class="QLineEdit" name="lineEdit"> 158 <property name="geometry"> 159 <rect> 160 <x>10</x> 161 <y>350</y> 162 <width>411</width> 163 <height>20</height> 164 </rect> 165 </property> 166 </widget> 167 <widget class="QLineEdit" name="lineEdit_2"> 168 <property name="geometry"> 169 <rect> 170 <x>430</x> 171 <y>200</y> 172 <width>113</width> 173 <height>20</height> 174 </rect> 175 </property> 176 </widget> 177 <widget class="QPushButton" name="pushButton_11"> 178 <property name="geometry"> 179 <rect> 180 <x>560</x> 181 <y>200</y> 182 <width>131</width> 183 <height>23</height> 184 </rect> 185 </property> 186 <property name="text"> 187 <string>设置共享内存的关键字</string> 188 </property> 189 </widget> 190 <widget class="QPushButton" name="pushButton_12"> 191 <property name="geometry"> 192 <rect> 193 <x>550</x> 194 <y>40</y> 195 <width>75</width> 196 <height>23</height> 197 </rect> 198 </property> 199 <property name="text"> 200 <string>分配内存</string> 201 </property> 202 </widget> 203 <widget class="QPushButton" name="pushButton_13"> 204 <property name="geometry"> 205 <rect> 206 <x>450</x> 207 <y>350</y> 208 <width>75</width> 209 <height>23</height> 210 </rect> 211 </property> 212 <property name="text"> 213 <string>写</string> 214 </property> 215 </widget> 216 <widget class="QPushButton" name="pushButton_14"> 217 <property name="geometry"> 218 <rect> 219 <x>560</x> 220 <y>350</y> 221 <width>75</width> 222 <height>23</height> 223 </rect> 224 </property> 225 <property name="text"> 226 <string>读</string> 227 </property> 228 </widget> 229 </widget> 230 <widget class="QMenuBar" name="menubar"> 231 <property name="geometry"> 232 <rect> 233 <x>0</x> 234 <y>0</y> 235 <width>747</width> 236 <height>23</height> 237 </rect> 238 </property> 239 </widget> 240 <widget class="QStatusBar" name="statusbar"/> 241 </widget> 242 <resources/> 243 <connections/> 244 </ui>
作者:疯狂Delphi
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
欢迎关注我,一起进步!扫描下方二维码即可加我