我是QT的新手。我已经看到QT为共享内存提供的基本示例,但我想使用共享内存共享结构。我怎样才能实现它?
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();
}
在接收函数中我正在缓冲区中获取数据,但我无法将其转换为可回复的结构。
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();
}
答案 0 :(得分:0)
您正在使用QDataStream
编写单个字段,但使用memcpy
作为结构读取。这会引起问题!
您应该以与撰写时相同的方式阅读数据。
示例(假设TestStruct
的成员a,b和c与structa
的类型相同):
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&)
。你可以用这个:
// Use intermediate qint8 (or quint8)
qint8 t;
in >> t;
char x = t;
您可以立即编写完整的结构:
// 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();
但要注意!这可能不会有可能!参见例如this question填充问题。 我不推荐这种方法
this blog中有一个很好的指南。它为Qt。
中的常规序列化方法提供了基础知识基本思想是将对象序列化为QVariant
。 QVariant
可以存储多种类型,包括QVariantMap
,这是QString => QVariant
的地图。因此,您可以创建分层结构。
可以使用QVariant
对这些QDataStream
进行搜索。
概要如下:
// 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;
// ...
}
您可以按如下方式使用:
// 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;