2016-05-24 15 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 veriable обратно.

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 имеет член а, Ь и с тем же типа, как 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(); 

Update:
Если у вас есть простые 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(); 

Но будьте осторожны! Это, вероятно, не будет protable! См. this question. Я не рекомендую этот метод

А вообще Qt сериализации подход

Существует довольно хорошее руководство в this blog. Он дает основы для общего метода сериализации в Qt.

Основная идея состоит в сериализации объектов в QVariant. A QVariant может хранить множество типов, в том числе QVariantMap, который является картой от QString => QVariant. Поэтому вы можете создавать иерархические структуры.

С этими QVariant s может быть произведено исцеление с помощью 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; 
+0

Я тоже пробовал эту вещь. char * pData = новый символ [sizeof (tmp)]; memcpy (pData, buffer.data(), sizeof (tmp)); Но снова я должен преобразовать его в тип Struct –

+0

в операторе дает ошибку для char. нет совпадений для 'operator >>' (типы операндов: «QDataStream» и «char») in >> tmp.b; –

+0

Спасибо king_nak. Но есть ли способ, в котором мы можем напрямую преобразовать данные всего буфера в тип структуры, а не использовать несколько операторов «in >>». –