Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> memory stream в C++, Работа с памятью как с потоками.. 
V
    Опции темы
Superklug
Дата 18.6.2010, 09:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Доброго времени суток!

Существуют ли в C++ средства для работы с памятью как с потоком?

Есть класс, для которого есть возможность сериализации. В поток записываются бинарные данные.

Если нужно записать объект в память, то в качестве потока использую std::stringstream, затем преобразование вида:
Код

const void *data = (const void*)ss.str().c_str();


А вот с десериализацией возникла проблема( Есть void*, а как с ним работать как с потоком - не знаю. Если бы был известен размер, можно было бы просто скопировать в stringstream, но размера я не знаю.

Пока две мысли: написать копии функций для сериализации/десериализации только не для потоков, а для void*. Либо создать свой класс потока (унаследоать от стандартного потока stl). Ни тот, ни другой вариант не нравится(

Надеюсь на вашу помощь.. Заранее спасибо!
PM MAIL   Вверх
azesmcar
Дата 18.6.2010, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



измени сериализацию и пиши размер в первые 2/4 байта бинарных данных.
PM   Вверх
Superklug
Дата 18.6.2010, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



azesmcar, возможности писать размер - нет. Формат бинарных данных определен строго...
А что значит измени сериализацию?
PM MAIL   Вверх
azesmcar
Дата 18.6.2010, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Superklug @  18.6.2010,  11:10 Найти цитируемый пост)
А что значит измени сериализацию? 

значит измени код, который сериализирует твой объект, и добавь в сериализацию размер.

Цитата(Superklug @  18.6.2010,  11:10 Найти цитируемый пост)
возможности писать размер - нет. Формат бинарных данных определен строго...

довольно странный формат данных, в котором не указывается размер, каким образом предполагается обратное приведение?
PM   Вверх
Superklug
Дата 18.6.2010, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Цитата(azesmcar @  18.6.2010,  11:11 Найти цитируемый пост)
довольно странный формат данных, в котором не указывается размер, каким образом предполагается обратное приведение? 

Разумеется там указывается размер. Просто это не размер всего блока данных. Например массив из двух строк: первый размер - 2, а затем еще для каждой строки. ( 2 6"привет" 5"hello"). Ну это очень грубо говоря) Вобщем оценить размер всего блока данных достаточно сложно...
Хотелось бы читать данные из памяти как из потока...
PM MAIL   Вверх
Superklug
Дата 18.6.2010, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Цитата(Earnest @  18.6.2010,  11:17 Найти цитируемый пост)
Используй  strstream 

Я бы рад) Да вот только не знаю как... Как перевести из void* в stringstream не зная размера?

Добавлено через 1 минуту и 40 секунд
Earnest, прошу прощения.. Не правильно прочитал. Сейчас разберусь с strstream.. На первый взгляд - то, что нужно! Спасибо!
PM MAIL   Вверх
Earnest
Дата 18.6.2010, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Да, не заметила, что ты не знаешь размер буфера...
Нехорошо, присоединяюсь к предыдущему оратору: измени код так, чтобы знать. Ведь откуда-то ты этот буфер берешь, не с неба же. 


--------------------
...
PM   Вверх
azesmcar
Дата 18.6.2010, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Superklug @  18.6.2010,  11:16 Найти цитируемый пост)
Хотелось бы читать данные из памяти как из потока... 

читай как хочешь, но в конечном итоге это чтение из бинарного блока данных, и если о его размере ничего не известно то никакой адаптер в виде потоков не поможет.

Цитата(Superklug @  18.6.2010,  11:10 Найти цитируемый пост)
Формат бинарных данных определен строго...

кстати это не меняет формата данных, будешь считать, что твои данные начинаются по смещению 2 байта, а первые 2 будешь использовать для хранения размера.

Это сообщение отредактировал(а) azesmcar - 18.6.2010, 11:26
PM   Вверх
Superklug
Дата 18.6.2010, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Цитата(Earnest @  18.6.2010,  11:20 Найти цитируемый пост)
Нехорошо, присоединяюсь к предыдущему оратору: измени код так, чтобы знать. Ведь откуда-то ты этот буфер берешь, не с неба же.  

=)
Сейчас поясню подробней...
Есть класс который представляет собой что-то похожее на Variant. Его упаковывают в особый бинарный формат. Разумеется когда упаковали размер известен. Эти упакованные данные передаются в функции DLL как const void*. Можно конечно в эти же функции передавать и размер (отдельным параметром), но хочется обойтись без этого. Формат же содержит размер, хоть и не явно.
Если бы была возможность работать с памятью, как с потоком, то никаких проблем не было бы. Т.е. последовательно читать байты из памяти и все...
Можно (наверное) написать наследника от istream и определить нужные операции. Но это решение кажется каким-то громоздким. Вот и подумал, что существует способ получше.
PM MAIL   Вверх
azesmcar
Дата 18.6.2010, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Superklug @  18.6.2010,  11:26 Найти цитируемый пост)
Можно (наверное) написать наследника от istream и определить нужные операции. Но это решение кажется каким-то громоздким. Вот и подумал, что существует способ получше. 

повторяюсь, это сводится к чтению того же бинарного блока данных, то, что ты хочешь - обыкновенный адаптер, в конечном итоге этот код чтения должен быть где-то написан, а как его писать, если ты размера не знаешь.
PM   Вверх
Superklug
Дата 18.6.2010, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Не понимаю =(
Рассмотрю пример, приведенный выше...
Есть void*. Считываю первые 4 байта (int) - получаю количество элементов массива (2шт). Затем считываю еще 4 байта - получаю число символов в строке. Затем считываю соответствующее число байт для строки. После этого так же считываю вторую строку.
Все корректно считается не смотря на то, что суммарного размера (23 байта) я не знал.
PM MAIL   Вверх
azesmcar
Дата 18.6.2010, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Superklug

Цитата(Superklug @  18.6.2010,  11:36 Найти цитируемый пост)
Есть void*. Считываю первые 4 байта (int) - получаю количество элементов массива (2шт). Затем считываю еще 4 байта - получаю число символов в строке. Затем считываю соответствующее число байт для строки. После этого так же считываю вторую строку.

и сколько так? как узнать, что пора остановиться?

Ты же сам писал, что тебе нужен размер всего блока и это бы решило проблему.

Цитата(Superklug @  18.6.2010,  09:36 Найти цитируемый пост)
А вот с десериализацией возникла проблема( Есть void*, а как с ним работать как с потоком - не знаю. Если бы был известен размер, можно было бы просто скопировать в stringstream, но размера я не знаю.

ну так добавь размер, в чем проблема?


PM   Вверх
Superklug
Дата 18.6.2010, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Цитата(azesmcar @  18.6.2010,  11:39 Найти цитируемый пост)
и сколько так? как узнать, что пора остановиться?

Все просто.. Первый элемент - число элементов массива. Как только считал столько элементов, так и останавливаешься.
К слову там не обязательно массивы и строки. Это пример просто иллюстрирует принцип.
PM MAIL   Вверх
azesmcar
Дата 18.6.2010, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Superklug @  18.6.2010,  11:45 Найти цитируемый пост)
Все просто.. Первый элемент - число элементов массива. Как только считал столько элементов, так и останавливаешься.

уже что-то, хоть это известно smile 
а элементы массива разных размеров?
PM   Вверх
Superklug
Дата 18.6.2010, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 16.6.2006

Репутация: нет
Всего: нет



Цитата(azesmcar @  18.6.2010,  11:48 Найти цитируемый пост)
уже что-то, хоть это известно  
а элементы массива разных размеров? 

Еще раз повторяюсь. Размер косвенно известен. Т.е. вовремя остановиться - не проблема. 
Там самые разные типы... Строки, числа, массивы, объекты, бинарные данные. Структуры могут быть вложены (например массив массивов). Но все размеры известны, все можно корректно считать.

Просто средство для считывания (десериализации) работает с потоками...
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1142 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.