② 通过构造函数QSharedMemory::QSharedMemory (QObject * parent = 0 )构造实例对象,之后调用setKey()函数为该实例对象设置关键字。 例如: QSharedMemory* sharememory; sharememory = new QSharedMemory(); sharememory->setKey("QSharedMemoryExample "); 2、创建共享内存 bool QSharedMemory::create ( int size, AccessMode mode =ReadWrite )为QSharedMemory类实例对象创建一个空间大小为size的共享内存,该内存空间默认的访问方式为可读可写。共享内存创建成功返回true,否则返回false。QSharedMemory类定义一个枚举类变量AccessMode,指定了两种共享内存的访问方式: QSharedMemory::ReadOnly 只读方式访问共享内存 QSharedMemory::ReadWrite 读写方式访问共享内存
3、关联共享内存 bool QSharedMemory::attach ( AccessMode mode =ReadWrite )将以关键字key命名的共享内存和当前程序进行关联,共享内存默认的访问方式为可读可写。如果程序和共享内存关联成功,返回true,否则返回false。
4、分离共享内存 bool QSharedMemory::detach ()解除共享内存和程序的关联,即调用该函数后,程序不可以再访问共享内存。如果该共享内存被多个程序实例所关联,当最后一个程序实例和共享内存解除关联后,该共享内存将由操作系统自动释放掉。分离操作成功,返回true。如果返回false,通常意味着该共享内存和程序分离失败,或者其他程序当前正在访问该共享内存,分离操作执行失败。5、判断共享内存的关联状态 bool QSharedMemory::isAttached ()const该函数用来判断程序(调用该函数的程序)是否和共享内存进行关联,是返回true,否返回false。 6、设置/获取共享内存的关键字 QString QSharedMemory::key ()const //获取共享内存关键字Qt应用程序通过关键字来辨识共享内存。key ()函数用来获取共享内存的关键字,如果没有指定实例对象的关键字,或者共享内存的关键字是由nativeKey ()函数指定的话,则返回空。 void QSharedMemory::setKey (const QString & key ) //设定共享内存关键字setKey () 函数用来为共享内存段设定关键字 ( 为共享内存命名 ) ,如果参数 key 的值和构造函数或者之前指定的关键字相同的话,则该函数将不做任何操作,直接返回。
7、锁定/解锁共享内存 bool QSharedMemory::lock () //锁定共享内存如果共享内存资源当前处于释放状态,进程调用该函数将共享内存中的资源锁定,并返回true。其他进程将不能访问该共享内存。如果共享内存被其他进程占用时,则该函数会一直处于阻塞状态,直到其他进程使用完毕,释放共享内存资源。bool QSharedMemory::unlock () //解锁共享内存如果共享内存资源被当前进程所占有,调用该函数将解锁该共享资源,并返回true。如果当前进程没有占用该资源,或者共享内存被其他进程访问,则不做任何操作并返回false。
为了保证共享内存中数据的完整性,当一个进程在读写共享内存的时候,其他进程不允许对该共享区域进行访问。QSharedMemory类提供了lock()函数和unlock()函数来实现这一共享内存访问机制。某一程序对共享内存进行读写操作之前,需要调用lock()函数锁定该共享内存,之后独享共享内存中的数据,并对数据进行读写等操作。共享内存访问完毕,调用unlock()函数,释放共享内存的使用权限。 8、错误原因 SharedMemoryError QSharedMemory::error ()const当共享内存出错时,调用该函数显示相应的错误代码。QString QSharedMemory::errorString ()const当共享内存出错时,调用该函数,以文本形式显示错误原因。9、获取共享内存的地址 const void *QSharedMemory::constData ()constvoid * QSharedMemory::data () const void *QSharedMemory::data ()const //重载函数程序关联共享内存的前提下,调用该函数返回共享内存中数据的起始地址。如果没有关联共享内存,则返回0。
10、获取共享内存的大小 int QSharedMemory::size ()const调用该函数将返回程序所关联的共享内存的大小(字节)。如果没有关联的共享内存,则返回0。
二、示例代码 ① main.cpp源文件 #include <QtGui/QApplication> #include "dialog.h" #include <QTextCodec> int main(int argc, char *argv[]) {
QApplication application(argc, argv); //Qt国际化显示 QTextCodec::setCodecForTr(QTextCodec::codecForName("GB18030")); QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB18030")); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB18030")); Dialog dialog; dialog.show(); return application.exec(); }
② dialog.h头文件 #ifndef DIALOG_H #define DIALOG_H #include <QDialog> //调试用头文件
#include <QDebug> #include <QMessageBox> #include <QFileDialog> #include <QDir> #include <QPixmap> #include <QImage> #include <QDataStream> #include <QBuffer> #include <QSharedMemory> namespace Ui { class Dialog; }
class Dialog : public QDialog {
Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); public slots: void loadFromFile(); //载入图片按钮 响应函数 void loadFromMemory(); //显示图片按钮 响应函数 private: Ui::Dialog *ui; QSharedMemory *sharememory; //定义共享内存实例指针 bool first_flag; //判断是否是首次加载文件 };
#endif // DIALOG_H ③ dialog.cpp源文件 #include "dialog.h" #include "ui_dialog.h" #define DEBUG //调试开关 Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) {
ui->setupUi(this); QObject::connect(ui->PBtn_Load,SIGNAL(clicked()),this,SLOT(loadFromFile())); QObject::connect(ui->PBtn_Display,SIGNAL(clicked()),this,SLOT(loadFromMemory())); sharememory = new QSharedMemory(); //构造实例对象 sharememory->setKey("QSharedMemoryExample"); //为实例对象指定关键字(给共享内存命名) first_flag = true; }
Dialog::~Dialog() {
delete ui; }
//载入图片按钮响应函数
void Dialog::loadFromFile() {
if(sharememory->isAttached()) //检测程序当前是否关联共享内存 sharememory->detach(); //解除关联 ui->Label_Display->setText(tr("请选择一张图片")); QString filename = QFileDialog::getOpenFileName( this,"打开",QString(),tr("Image (*.png *.xpm *.jpg)")); QImage image; if(!image.load(filename)) //将打开的图片文件和QImage实例关联 { ui->Label_Display->setText(tr("您选择的不是图片文件,请重新选择")); return; } ui->Label_Display->setPixmap(QPixmap::fromImage(image)); QBuffer buffer; buffer.open(QBuffer::ReadWrite); //构建并打开数据缓冲区,访问方式为读写 #ifdef DEBUG qDebug()<<"新建缓冲区的大小为:"<<buffer.size(); //测试缓冲区大小(一般为0) #endif
QDataStream in(&buffer); //建立数据流对象,并和缓冲区相关联 in << image; //向缓冲区写入数据 int size = buffer.size(); //获取写入数据的大小(图片的大小) #ifdef DEBUG //调试部分 qDebug()<<"缓冲区的大小为:"<<size; qDebug()<<sharememory->key(); qDebug()<<sharememory->nativeKey(); // sharememory->setKey("共享内存"); //修改共享内存的关键字,将无法访问共享内存 qDebug()<<sharememory->key(); qDebug()<<sharememory->nativeKey(); qDebug()<<sharememory->error(); qDebug()<<sharememory->errorString(); #endif
if(true == first_flag) { if (!sharememory->create(size)) //创建共享内存,大小为size { ui->Label_Display->setText(tr("无法创建共享内存段")); qDebug()<<sharememory->errorString(); return; } first_flag = false; qDebug()<<sharememory->size(); //显示共享内存的大小 } //对共享内存进行读写操作 sharememory->lock(); //锁定共享内存 char *to = (char*)sharememory->data(); //获取共享内存中的地址 const char *from = buffer.data().data(); //获取有效数据在缓冲区中的地址 memcpy(to, from, qMin(sharememory->size(), size)); //将缓冲区中的数据复制到共享内存 sharememory->unlock(); //释放共享内存 }
//显示图片按钮响应函数
void Dialog::loadFromMemory() {
if (!sharememory->attach()) //关联共享内存 { ui->Label_Display->setText("无法关联共享内存"); return; } QBuffer buffer; //构建缓冲区 QDataStream out(&buffer); //建立数据流对象,并和缓冲区关联 QImage image; //对共享内存进行读写操作 sharememory->lock(); //锁定共享内存 //初始化缓冲区中的数据,setData函数用来初始化缓冲区。 //该函数如果在open()函数之后被调用,则不起任何作用。 //buffer.open(QBuffer::ReadOnly); //解除注释,则setData函数不起作用,无法加载内存中数据 buffer.setData((char*)sharememory->constData(), sharememory->size()); buffer.open(QBuffer::ReadOnly); //只读方式打开缓冲区 out >> image; //将缓冲区的数据写入QImage对象 sharememory->unlock(); //释放共享内存 sharememory->detach(); //解除程序和共享内存的关联 ui->Label_Display->setPixmap(QPixmap::fromImage(image)); //显示图片 }
|
|