2016-05-24 12 views
0

Ich bin neu in der QT. Ich habe das grundlegende Beispiel von QT für Shared Memory gesehen, aber ich möchte Struktur mit Shared Memory teilen. Wie kann ich es erreichen?Pass Struktur mit 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(); 
} 

In Empfangsfunktion ich die Daten direkt im Buffer bekommen, aber ich bin nicht in der Lage, es zu konvertieren veriable zurück zu 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

Können Sie zumindest einige Code zur Verfügung stellen, damit wir sehen können, was Sie bereits versucht haben. –

+0

Hallo, ich habe meinen Code gepostet. Ich schreibe sowohl Sender- als auch Empfänger-Pufferdaten in Datei und beide sind gleich, aber auf der Empfängerseite kann ich es nicht zu Strukturvariablen typen dereferenzieren. –

Antwort

0

Sie schreiben einzelne Felder ein QDataStream verwenden, sondern als struct Lesen memcpy verwenden. Dies wird Probleme verursachen!

Sie sollten die Daten auf die gleiche Weise lesen, wie Sie schreiben.

Beispiel (unter der Annahme TestStruct Mitglieder a, b und c des gleichen Typs wie 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(); 

aktualisieren:
Wenn Sie einfach char s in Ihrer Struktur haben, wird der Extraktionscode nicht arbeiten, da es keine operator>>(QDataStream&, char&) gibt. Sie können diese verwenden:

// Use intermediate qint8 (or quint8) 
qint8 t; 
in >> t; 
char x = t; 

Serialisierung komplette Struktur

Sie können sofort die komplette Struktur schreiben:

// 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(); 

Aber Vorsicht! Dies wird wahrscheinlich nicht protable sein! Siehe z.B. this question für Padding-Probleme. ich diese Methode nicht

Eine allgemeine Qt Serialisierung Ansatz

Es gibt eine ziemlich gute Anleitung in this blog empfehlen. Es gibt die Grundlagen für eine allgemeine Serialisierungsmethode in Qt.

Die Grundidee besteht darin, Objekte in QVariant s zu serialisieren. A QVariant kann viele Arten speichern, einschließlich einer QVariantMap, die eine Karte von QString => QVariant ist. Daher können Sie hierarchische Strukturen erstellen.

Diese QVariant s können mit einem QDataStream sucherialisiert werden.

Der Umriss ist wie folgt:

// 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; 
    // ... 
} 

Sie diese wie folgt verwenden:

// 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

Ich habe das Ding auch ausprobiert. char * pData = neues Zeichen [sizeof (tmp)]; memcpy (pDaten, Puffer.data(), sizeof (tmp)); Aber wieder muss ich es in Struct Typ konvertieren –

+0

in Operator gibt Fehler für Char. keine Übereinstimmung für 'Operator >>' (Operandentypen sind 'QDataStream' und 'char') in >> tmp.b; –

+0

Danke König_nak. Aber gibt es eine Möglichkeit, wo wir ganze Pufferdaten direkt in Strukturtyp konvertieren können, anstatt mehrere "in >>" -Anweisungen zu verwenden. –