2016-05-24 57 views
0

我是QT新手。我已经看到了QT为共享内存提供的基本示例,但我想使用共享内存共享结构。我怎样才能实现它?使用QSharedMemory传递结构

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可返回的数据。

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(); 
} 
+1

你能至少提供一些代码,这样我们就可以看到你已经尝试过。 –

+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 s时,提取码不会工作,因为没有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用于填充问题。 我不推荐这种方法

一般Qt的序列化方式

有一个在this blog相当不错的指南。它给出了Qt中的一般序列化方法的基础知识。

其基本思想是将对象序列化为QVariant s。 A QVariant可以存储多种类型,包括QVariantMap,这是一个来自QString => QVariant的地图。因此,您可以创建分层结构。可以使用QDataStream来搜索这些QVariant

大纲如下:

// 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; 
+0

我也试过这个东西。 char * pData = new char [sizeof(tmp)]; memcpy(pData,buffer。data(),sizeof(tmp)); 但我再次必须将其转换为结构类型 –

+0

在运算符给char错误。 'operator >>'不匹配(操作数类型为'QDataStream'和'char') in >> tmp.b; –

+0

谢谢king_nak。 但是有什么办法可以将整个缓冲区数据直接转换为结构类型,而不是使用多个“in >>”语句。 –