首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用QSharedMemory的Pass结构

使用QSharedMemory的Pass结构
EN

Stack Overflow用户
提问于 2016-05-24 06:31:04
回答 1查看 1.5K关注 0票数 0

我是新来的。我已经看到了QT为共享内存提供的基本示例,但我希望使用共享内存共享结构。我怎样才能做到这一点?

代码语言:javascript
复制
void Dialog::Send()
{
if (sharedMemory.isAttached())
    detach();
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
QDataStream out(&buffer);
out << structa->a;
out << structa->b;
out << structa->c;
int size = buffer.size();
  if (!sharedMemory.create(size))
{
    ui.label->setText(tr("Unable to create shared memory segment."));
    return;
}
sharedMemory.lock();
char *to = (char*)sharedMemory.data();
const char *from = buffer.data().data();
memcpy(to, from, qMin(sharedMemory.size(), buffersize));
sharedMemory.unlock();
}

在接收函数中,我在缓冲区中获得数据,但无法将其转换为Struct可验证返回。

代码语言:javascript
复制
void Dialog::Receive()
{   
if (!(sharedMemory.attach()))
{
    ui.label->setText(tr("Unable to attach to shared memory segment.\n" \
                         "Load an image first."));
    return;
}
QByteArray byteArray;
QBuffer buffer(&byteArray);
QDataStream in(&buffer);
TestStruct tmp;                                     //Re-make the struct
sharedMemory.lock();
buffer.setData((char*)sharedMemory.constData(), sizeof(tmp));
buffer.open(QBuffer::ReadOnly);
int nSize = ((buffer.size()));
memcpy(&tmp, buffer.data().data(), nSize);
qDebug()<< " tmp.a = "<<tmp.a;
qDebug()<< " tmp.b = "<<tmp.b;
qDebug()<< " tmp.c = "<< tmp.c;
sharedMemory.unlock();
sharedMemory.detach();
}
EN

回答 1

Stack Overflow用户

发布于 2016-05-24 09:13:48

您正在使用QDataStream编写单个字段,但使用memcpy作为结构进行读取。这会引起问题的!

你应该用和你写的一样的方式来阅读数据。

示例(假设TestStruct的成员a、b和c与structa类型相同):

代码语言:javascript
复制
QBuffer buffer;
sharedMemory.lock();
buffer.setData(sharedMemory.constData(), sharedMemory.size());
sharedMemory.unlock();

buffer.open(QIODevice::ReadOnly);
QDataStream in(&buffer);
TestStruct tmp;
in >> tmp.a;
in >> tmp.b;
in >> tmp.c;
buffer.close();

更新

如果您的结构中有简单的char,则提取代码将无法工作,因为没有operator>>(QDataStream&, char&)。你可以用这个:

代码语言:javascript
复制
// Use intermediate qint8 (or quint8)
qint8 t;
in >> t;
char x = t;

序列化完整结构

您可以一次编写完整的结构:

代码语言:javascript
复制
// Writing:
TestStruct structa; // Initialized as needed
QBuffer buffer;
buffer.open(QIODevice::WriteOnly);
buffer.write(&structa, sizeof(TestStruct));
buffer.close();

// Reading:
QBuffer buffer;
buffer.setData(sharedMemory.constData(), sharedMemory.size());
buffer.open(QIODevice::ReadOnly);
TestStruct out;
buffer.read(&out, sizeof(TestStruct));
buffer.close();

,但是要小心!,这可能是不可能的!有关填充问题,请参见例如这个问题。我不推荐这种方法。

一种通用的Qt序列化方法

这个博客中有相当好的指南。它为Qt中的通用序列化方法提供了基础知识。

其基本思想是将对象序列化为QVariantQVariant可以存储许多类型,包括QVariantMap,这是来自QString => QVariant的映射。因此,你可以创建等级结构。

这些QVariant可以使用QDataStream进行海运。

概要如下:

代码语言:javascript
复制
// Enables << and >> for all QVariant supported types
template <typename T>
void operator << (QVariant &v, const T &d) {
    v = QVariant::fromValue<T>(d);
}
template <typename T>
void operator >> (const QVariant &v, T &d) {
    d = v.value<T>();
}

// Enable << and >> for your own type
void operator << (QVariant &v, const TestStruct &t) {
   QVariantMap m;
   m["a"] << t.a; // Re-use already defined operator <<
   m["b"] << t.b;
   m["c"] << t.c; 
   // ...
   v << m; // Put mapped custom type into a single QVariant
}
void operator >> (const QVariant &v, TestStruct &t) {
   QVariantMap m;
   // Load mapped type
   v >> m;
   m["a"] >> t.a; // Re-use already defined operator >>
   m["b"] >> t.b;
   m["c"] >> t.c; 
   // ...
}

您可以如下所示:

代码语言:javascript
复制
// Writing
TestStruct structa;
QVariant v;
v << structa;
QBuffer buffer;
buffer.open(QIODevice::WriteOnly);
QDataStream str(&buffer);
str << v;

// Reading
QBuffer buffer;
buffer.setData(...);
buffer.open(QIODevice::ReadOnly);
QDataStream str(&buffer);
str >> v;
TestStruct structa;
v >> structa;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37405956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档