Название: Сериализация QString содержащей структуры. Отправлено: __Heaven__ от Май 17, 2013, 06:09 Всем снова привет!
Есть структура, которую я записываю в бинарный файл с помощью QDataStream::writeRawData. Отдельно выписываю каждый QString через оператор <<. При чтении этого файла, чтение структуры проходит успешно. А вот при чтении в QString выдает ошибку (realloc или чё-то там...) Вскоре понял, что это происходит из-за того значения, которое передаётся в QString при чтении файла. Решил проблему с помощью QString::clear() и последующим чтением QString из файла. Только теперь уже проблема возникла иная: при закрытии программы выскакивает что-то вроде heap corruped. Вопрос: какое именно значение из QString записывается при сериализации и как при десериализации избежать переписывания QString переменных или "сохранить нынешние значения QString (которое затирается при деериализации) -> прочитать файл -> восстановить это значение) Спасибо Название: Re: Сериализация QString содержащей структуры. Отправлено: xokc от Май 17, 2013, 11:56 Трижды перечитал вопрос - так и не понял про что он. Давай, что-ли с публикации проблемного кода начнем?
Название: Re: Сериализация QString содержащей структуры. Отправлено: __Heaven__ от Май 18, 2013, 11:27 Сама структура:
Код: #ifndef SOLUTIONSETTINGS_H Её записываем в файл. Код: out.writeRawData(reinterpret_cast<char*>(&_settings), sizeof(_settings)); Код: SolutionSettings _settings; Код: QFile binFile(slmFilePath); Название: Re: Сериализация QString содержащей структуры. Отправлено: __Heaven__ от Май 18, 2013, 11:42 При чтении уже в другой программе:
Код: in.readRawData(reinterpret_cast<char*>(&settings), sizeof(settings)); Код: QFile file(filePath); для чтения строк изначально написал Код: in >> settings.wayType; То есть, я полагаю, что при чтении из файла целиком структуры, в элементы QString были записаны какие-то произвольные значения (которые были рабочими при записи в файл). Таким образом, эти значения дают понять, что при выполнении некого деструктора (который выполняется по завершению программы) производится очистка памяти по тем самым значениям, которые были вписаны в структуру из файла, но они являются не актуальными, так как не относятся к выполняемому процессу, а просто были считаны из файла. Название: Re: Сериализация QString содержащей структуры. Отправлено: thechicho от Май 18, 2013, 11:48 а чо QSettings не воспользуетесь?
Название: Re: Сериализация QString содержащей структуры. Отправлено: mutineer от Май 18, 2013, 11:52 Писать QString в виде бинарного потока в одном процессе и вычитывать в другом это очень опасно, он наверняка имеет какие-то внутренние указатели, которые в другой программе невалидны. Не делай так, записывай всю структуру через QDataStream и операторы записи в поток
Название: Re: Сериализация QString содержащей структуры. Отправлено: __Heaven__ от Май 18, 2013, 12:36 а чо QSettings не воспользуетесь? Так как это не единственное, что я записываю в файл. Туда ещё идёт свыше 1000 QVectorПисать QString в виде бинарного потока в одном процессе и вычитывать в другом это очень опасно, он наверняка имеет какие-то внутренние указатели, которые в другой программе невалидны. Не делай так, записывай всю структуру через QDataStream и операторы записи в поток вот я про эти указатели и говорю. Как-то мучительно получается по отдельности записывать и считывать каждый элемент в отдельности + при добавлении элементов в структуру нужно искать чтение и запись и снова добавлять... Уверен, что должен быть какой-то другой способ. У меня появились некоторые идеи, сейчас попробую их спрораммировать, позже отпишусь по результатам, может кому полезно будетНазвание: Re: Сериализация QString содержащей структуры. Отправлено: mutineer от Май 18, 2013, 12:40 Перегрузи операторы << и >> для своей структуры и тогда все будет выглядеть просто как
Код
и при изменении структуры поменять надо будет только эти два оператора Название: Re: Сериализация QString содержащей структуры. Отправлено: __Heaven__ от Май 18, 2013, 14:52 Нашёл выход, более подходящий для меня!
Запись структуры оставить такой же, как я описывал выше. Но, конечно, как в моём случае вписываются лишние 5 * sizeof(QString) байт - думаю, для меня это не критично. Перед чтением файла нужно сохранить значения в каждом из QString. А после чтения восстановить их на прежние места. Иными словами: Код: char* strings[] = Теперь изменение структуры никак не повлияет на код чтения/записи. Если не трогать классы. Спасибо всем за советы. Название: Re: Сериализация QString содержащей структуры. Отправлено: Igors от Май 18, 2013, 15:04 Впечатление "хоть говори - хоть стреляЙ" :) Просто-напросто НЕ используйте readRawData/writeRawData, они только для сишных структур (и то не всегда). Пишите/читайте QString операторами << >> - это все что нужно.
[/offtop]Не, не дойдет :'( Название: Re: Сериализация QString содержащей структуры. Отправлено: mutineer от Май 18, 2013, 15:19 Ужас какой...
Название: Re: Сериализация QString содержащей структуры. Отправлено: Fregloin от Май 23, 2013, 09:19 да уж, код ужасен.
я всегда пишу C-строки в бинарные файлы для совместимости с другими прогами, которые написаны не на Qt/C++ (Delphi например). Название: Re: Сериализация QString содержащей структуры. Отправлено: __Heaven__ от Май 30, 2013, 11:19 Да, согласен, что код ужасен.
А в этой же теме хочу спросить по поводу writeRawData. Каким образом, не используя эту функцию можно записать данные (особенно double), чтобы они в последствии могли быть считаны в среде разработки delphi? Название: Re: Сериализация QString содержащей структуры. Отправлено: xokc от Май 31, 2013, 12:36 Код
Код
Название: Re: Сериализация QString содержащей структуры. Отправлено: Igors от Май 31, 2013, 13:31 Дополняя предыдущий ответ: перед записью надо установить QDataStream::setByteOrder с аргументом чтобы понравился дельфи (вероятно QDataStream::LittleEndian)
Название: Re: Сериализация QString содержащей структуры. Отправлено: __Heaven__ от Май 31, 2013, 20:00 Дополняя предыдущий ответ: перед записью надо установить QDataStream::setByteOrder с аргументом чтобы понравился дельфи (вероятно QDataStream::LittleEndian) Да, согласен. Вышеизложенное я изначально пробовал воплотить - не понравилось. |