Russian Qt Forum

Программирование => С/C++ => Тема начата: Igors от Май 21, 2013, 14:48



Название: Raw data
Отправлено: Igors от Май 21, 2013, 14:48
Добрый день

Файл грузится как raw data (read(.. data_size)) в блок памяти. Внутри файла/блока в числе всего прочего есть массив незатейливых структур
Код
C++ (Qt)
struct CHeader {
int mID;
...
void * mAddr;
}
 
Поле mAddr заполняется нулем при загрузке, в ходе работы хранит адрес показывающий "данные загружены".

Все это работает, но, естественно, в 64-bit накрывается медным тазом. Попытка сделать "нормально" (т.е. сериализрвать/сериализрвать каждое поле) в данном случае наталкивается на большие трудности. Как выкрутиться?

Спасибо


Название: Re: Raw data
Отправлено: Serr500 от Май 21, 2013, 15:11
1) Ну, как дурацкий вариант, если структуру можно менять:
Код:
union {
    __int64 mAddr64;
    void* m_Addr;
}

2) Не писать mAddr в файл, поскольку он всё равно обнуляется.

3) mAddr последний в структуре. Считываем блок в буфер чуть большего размера, откидываем хвост и копируем в структуру.


Название: Re: Raw data
Отправлено: Fat-Zer от Май 21, 2013, 15:29
Все это работает, но, естественно, в 64-bit накрывается медным тазом. Попытка сделать "нормально" (т.е. сериализрвать/сериализрвать каждое поле) в данном случае наталкивается на большие трудности. Как выкрутиться?
«нормальная сериализация» - единственный переносимый метод, который будет работать не зависимо от платформы, компилятора и его опций...видимо с остальными полями пока везло, что компилятор их не выравнивал...

если какая-то переносимость планируется, то это всё равно придётся делать это рано или поздно...


Название: Re: Raw data
Отправлено: Igors от Май 21, 2013, 15:57
«нормальная сериализация» - единственный переносимый метод, который будет работать не зависимо от платформы, компилятора и его опций...видимо с остальными полями пока везло, что компилятор их не выравнивал...

если какая-то переносимость планируется, то это всё равно придётся делать это рано или поздно...
Ой как хорошо (и главное - легко) давать такие советы :) Наверное я об этом и не догадывался!
Но это только "в теории". А в жизни - есть MacBinaryII файлы (нативвные ресурсы Mac) которые должны работать на Вындоуз. Есть код написанный лет 15 назад (не мной), который работал и всех устраивал. Осуждать человека за то что он не предвидел что адрес может быть и не 4 байта - нет оснований. Рыпаться переписывать все с нуля - наивно.

Да, надо заткнуть дырку, но это тоже работа. C'est la vie

2) Не писать mAddr в файл, поскольку он всё равно обнуляется.
Запись на Mac (внешней утилитой), на Вындоуз только чтение. Беда в том что никаких структур не создается (хотя типы есть), работа идет с образом файла (1:1) в памяти


Название: Re: Raw data
Отправлено: Old от Май 21, 2013, 16:26
На 64bit используем 32bit тип:
Код
C++ (Qt)
struct CHeader {
int mID;
...
uint32_t mAddrId;
}

Храним вместо указателя id, который ассоциируется с указателем на реальные данные.


Название: Re: Raw data
Отправлено: Igors от Май 21, 2013, 17:02
На 64bit используем 32bit тип:
Код
C++ (Qt)
struct CHeader {
int mID;
...
uint32_t mAddrId;
}

Храним вместо указателя id, который ассоциируется с указателем на реальные данные.

Как? Вы предлагаете хранить индекс ??? Но Вы ведь недавно яростно осуждали такой подход  :)
Ладно, но как отследить создание - удаление?


Название: Re: Raw data
Отправлено: Old от Май 21, 2013, 17:19
Как? Вы предлагаете хранить индекс ??? Но Вы ведь недавно яростно осуждали такой подход  :)
Ну мы тут пытаемся чужое криворукие исправлять. "Иногда и не так растопыришься". (с) :)
А насчет осуждения хранения индексов это глупости, если вы перечитаете то обсуждение и немного подумаете, то поймете что я осуждал не хранение индексов, а их использование во всех местах где надо и где не надо. Печально, что вы не понимаете разницы.

Ладно, но как отследить создание - удаление?
А как что создается и удаляется?


Название: Re: Raw data
Отправлено: Igors от Май 21, 2013, 18:06
Ну мы тут пытаемся чужое криворукие исправлять. "Иногда и не так растопыришься". (с) :)
А насчет осуждения хранения индексов это глупости, если вы перечитаете то обсуждение и немного подумаете, то поймете что я осуждал не хранение индексов, а их использование во всех местах где надо и где не надо. Печально, что вы не понимаете разницы.
Старый анекдот
Цитировать
Половой акт - $1
Наблюдение за актом - $10
Наблюдение за наблюдающим - $100
Поверьте, "наблюдение за понимающим" еще более интересно  :)

А как что создается и удаляется?
Просто malloc и free (ресурсы - "куски памяти", клиент знает что с ними делать). Поле адреса нужно чтобы отслеживать уже выделенный ресурс и дать его опять (возможно др клиенту).


Название: Re: Raw data
Отправлено: Old от Май 21, 2013, 18:14
Поверьте, "наблюдение за понимающим" еще более интересно  :)
Понимаю. Это как лучик света в темном царстве своего невежества. :)

Просто malloc и free (ресурсы - "куски памяти", клиент знает что с ними делать). Поле адреса нужно чтобы отслеживать уже выделенный ресурс и дать его опять (возможно др клиенту).
Подмените malloc/free, что бы они возвращали/принимали индексы + понадобится функция преобразующая индекс в указатель.


Название: Re: Raw data
Отправлено: Igors от Май 22, 2013, 07:58
Подмените malloc/free, что бы они возвращали/принимали индексы + понадобится функция преобразующая индекс в указатель.
Клиент использует адрес, подменить malloc/free я не могу. Надо связать адрем с индексом, но каким образом?


Название: Re: Raw data
Отправлено: Old от Май 22, 2013, 08:23
Клиент использует адрес, подменить malloc/free я не могу.
Клиент и будет получать адрес.
Код
C++ (Qt)
typedef uint32_t index_t;
 
index_t cur_index = 0;
std::map<index_t, void*> indexcache;
 
void *index2ptr( index_t idx )
{
   return indexcache[ idx ];
}
 
index_t imalloc( size_t sz )
{
   void *ptr = malloc( sz );
   assert( ptr );
 
   indexcache[ cur_index ] = ptr;
   return cur_index++;
}
 
void ifree( index_t idx )
{
   free( index2ptr( idx ) );
}
 
 

Надо связать адрем с индексом, но каким образом?
Нужен еще один уровень косвенности.
Код
C++ (Qt)
// Вместо:
void *data = ptr->mAddr;
 
// использовать:
void *data = index2ptr( ptr->mAddrId );
 


Название: Re: Raw data
Отправлено: Igors от Май 22, 2013, 09:01
Так cur_index неуклонно растет, из мапы ничего не удаляется


Название: Re: Raw data
Отправлено: Old от Май 22, 2013, 09:06
Так cur_index неуклонно растет, из мапы ничего не удаляется
Печаль.
Так вы подумайте как это исправить, а если не получиться пишите сюда ваш.


Название: Re: Raw data
Отправлено: Igors от Май 22, 2013, 09:30
Так вы подумайте как это исправить, а если не получиться пишите сюда ваш.
Ну что же Вы предлагаете решение которое нужно исправлять?  :)


Название: Re: Raw data
Отправлено: Old от Май 22, 2013, 09:32
Ну что же Вы предлагаете решение которое нужно исправлять?  :)
Я предложил идею, которую вы сразу не поняли. Пришлось добавлять псевдокод.