Страница 1 из 2
"Прозрачное" сжатие BLOB-полей. Как реализовать в
Добавлено: 30 авг 2006, 21:12
SAV
есть статья "Работа с BLOB-полями в клиентских приложениях InterBase и Firebird на основе компонентов FIBPlus" на
http://www.devrace.com/ru/fibplus/articles/2261.php ,там есть раздел "Уникальные возможности FIBPlus: Client BLOB-filters. "Прозрачное" сжатие BLOB-полей". Попытался повторить всё сделанное на С++Builder6,но возникли осложнения:
1) zStream,у меня нет в Builder,поэтому использовал ZLib,думаю что в этом нет ничего страшного.
2) Сделал как в статье,но то что в Delphi ReallocMem(Buffer, BufSize) в С++ это Buffer = realloc(Buffer,BufSize) - НЕ РАБОТАЕТ!!! - Access violation... как так?
Совсем запарился,может ошибка где,то в FIBPlus? Если нет то подсажите как разрешить,я уже начинаю подeмывать о техподдержке FIBPlus. Вот листинг процедуры:
Код: Выделить всё
void __fastcall PackBuffer(void *SourceBuf,int &SourceLen)
{
try
{
unsigned long DestLen=SourceLen*1.1+12;
Bytef * DstBuf=NULL;
DstBuf =(Bytef *) realloc(DstBuf,DestLen);
if (compress2 ( DstBuf, &DestLen,
(Bytef *)SourceBuf,SourceLen,
9)
!=_OK
)return;
// число (длина неупакованного буфера) преобразованное в строку
AnsiString SrcLenStr = IntToStr(SourceLen);
// количество символов строки
int SybolsLen =SrcLenStr.Length();
/* размер упакованног буфера c дописанным значением исходного значения*/
SourceLen =DestLen+SybolsLen+1;
SourceBuf = realloc(SourceBuf,SourceLen);/* Вот тут ACCESS VIOLATION и выходит!!!!*/
SourceBuf =(Bytef*) memcpy(SourceBuf, DstBuf,DestLen);
free(DstBuf);
((Bytef *)SourceBuf)[DestLen] = '#';// разделитель <блок данных>#<исходный размер>
//дописываем длину
int cntr=1;
for (int i= SourceLen-1;i>DestLen;i--)
((Bytef *)SourceBuf)[i]=(Bytef)SrcLenStr[cntr++];
}
catch (Exception &E)
{
ShowMessage("PackBuffer error\n"+E.Message);
Form1->pFIBTransaction1->Rollback();
}
}
Добавлено: 30 авг 2006, 21:26
Merlin
Вообще-то в таких случаях подемывать о техподдержке надо как бы в первую очередь... А так - жди а) Ц-шника, б) работающего с FIBPlus в) с блобами д) жмущего их чем ни попадя... Имхо долго ждать придётся.
Добавлено: 30 авг 2006, 22:10
SAV
Merlin писал(а):Вообще-то в таких случаях подемывать о техподдержке надо как бы в первую очередь... А так - жди а) Ц-шника, б) работающего с FIBPlus в) с блобами д) жмущего их чем ни попадя... Имхо долго ждать придётся.
В техподдеожку написал,пока тишина. А по поводу " жмущего их чем ни попадя..." это ты зря ZLib ооочень распространённая библиотека сжатия. Жаль что "Ц-шников" маловато на этом форуме

Re: "Прозрачное" сжатие BLOB-полей. Как реализоват
Добавлено: 30 авг 2006, 23:42
hvlad
SAV писал(а):есть статья "Работа с BLOB-полями в клиентских приложениях InterBase и Firebird на основе компонентов FIBPlus" на
http://www.devrace.com/ru/fibplus/articles/2261.php ,там есть раздел "Уникальные возможности FIBPlus: Client BLOB-filters. "Прозрачное" сжатие BLOB-полей". Попытался повторить всё сделанное на С++Builder6,но возникли осложнения:
1) zStream,у меня нет в Builder,поэтому использовал ZLib,думаю что в этом нет ничего страшного.
2) Сделал как в статье,но то что в Delphi ReallocMem(Buffer, BufSize) в С++ это Buffer = realloc(Buffer,BufSize) - НЕ РАБОТАЕТ!!! - Access violation... как так?
Код: Выделить всё
void __fastcall PackBuffer(void *SourceBuf,int &SourceLen)
{
try
{
unsigned long DestLen=SourceLen*1.1+12;
Bytef * DstBuf=NULL;
DstBuf =(Bytef *) realloc(DstBuf,DestLen);
Зачем realloc для пустого указателя ? Попробуй обычный alloc или new
Re: "Прозрачное" сжатие BLOB-полей. Как реализоват
Добавлено: 31 авг 2006, 06:30
SAV
hvlad писал(а):
Зачем realloc для пустого указателя ? Попробуй обычный alloc или new
В этом месте ошибок не возникает,к тому же даже в справке написано:
void *realloc(void *block, size_t size);
....................................................................
The block argument points to a memory block previously obtained by calling malloc, calloc, or realloc. If block is a NULL pointer, realloc works just like malloc.
"ACCESS VIOLATION" вываливается при попытке уменьшить количество выделенной памяти для SourceBuf,которое было выделено где-то в функции pFIBDataSet1->Post(), я объектный паскаль не очень то знаю,поэтому копание исходников пока не помогло
SourceBuf = realloc(SourceBuf,SourceLen);/* Вот тут ACCESS VIOLATION и выходит!!!!*/
Добавлено: 31 авг 2006, 08:30
Ivan_Pisarevsky
Я последний раз на С писал курсе на 4...
Фраза "уменьшаем размер буфера" слехка не нравица...
Коллега, вы в курсе, что не всякая последовательность байтов сживамется? после обработки этой библиотекой блоб может стать и больше первоначального.
Попробуй выделить память под новый указатель , а не уменьшать имеющийся.
Добавлено: 31 авг 2006, 08:51
Dimitry Sibiryakov
И вообще: если тебе дали указатель, это еще не значит что ты можешь делать с ним все что тебе вздумается. Может, это указатель на стековую переменную?.. А ты ее освобождать...
Добавлено: 31 авг 2006, 09:47
SAV
Ivan_Pisarevsky писал(а):Я последний раз на С писал курсе на 4...
Коллега, вы в курсе, что не всякая последовательность байтов сживамется? после обработки этой библиотекой блоб может стать и больше первоначального.
По поводу сжимаемости согласен,в коде отсутствует проверка после
compress2 ( DstBuf, &DestLen,(Bytef *)SourceBuf,SourceLen, 9), можно это учесть вот так if(SourceLen<=DestLen)return;
Ivan_Pisarevsky писал(а):
Попробуй выделить память под новый указатель , а не уменьшать имеющийся.
Это как? Если я сделаю новый указатель,он выделится в другом "месте" то функция вызвавшая этот фильтр ничего не получит измененный буфер,а будет ссылаться на "старый". Вобщем копаюсь пока. Значит никто в Builder не пытался сделать сжатие BLOB-полей,обидно,досадно

Re: "Прозрачное" сжатие BLOB-полей. Как реализоват
Добавлено: 31 авг 2006, 12:44
SAV
От Support второй день уже ничего не слышно. Подскажтите где пожно почитаь доки или найти рабочий пример на тему Client BLOB-filters в С++Builder для FIBPlus6.45
Добавлено: 31 авг 2006, 13:31
Dimitry Sibiryakov
Весь саппорт на пути к Бали

Re: "Прозрачное" сжатие BLOB-полей. Как реализоват
Добавлено: 31 авг 2006, 14:30
hvlad
SAV писал(а):"ACCESS VIOLATION" вываливается при попытке уменьшить количество выделенной памяти для SourceBuf,которое было выделено где-то в функции pFIBDataSet1->Post(), я объектный паскаль не очень то знаю,поэтому копание исходников пока не помогло
SourceBuf = realloc(SourceBuf,SourceLen);/* Вот тут ACCESS VIOLATION и выходит!!!!*/
Нужно смотреть, чем выделяется SourceBuf - менеджер памяти должен быть один и тот же
Добавлено: 31 авг 2006, 14:47
kdv
Весь саппорт на пути к Бали
ничего подобного.

это менеджмент на пути к Бали. А вот саппорт должен работать.
Добавлено: 31 авг 2006, 14:57
Merlin
kdv писал(а):Весь саппорт на пути к Бали
ничего подобного.

это менеджмент на пути к Бали. А вот саппорт должен работать.
Кста, как там прошёл ужин? В тёплой дружеской обстановке, переходящей в пение народных песен и так далее? Фотоотчётик какой-нить будет?
Re: "Прозрачное" сжатие BLOB-полей. Как реализоват
Добавлено: 31 авг 2006, 14:59
SAV
hvlad писал(а):Нужно смотреть, чем выделяется SourceBuf - менеджер памяти должен быть один и тот же
Вот и я про тоже! Исходники смотю... но не нашёл пока ... к тому же я не знаю аналога ReallocMem(Buffer, BufSize) в С++ кроме realloc.
Добавлено: 31 авг 2006, 15:29
Dimitry Sibiryakov
У меня такое впечатление что этот код вообще работать не может. Откуда ты его взял?
Добавлено: 31 авг 2006, 16:32
SAV
Dimitry Sibiryakov писал(а):У меня такое впечатление что этот код вообще работать не может. Откуда ты его взял?
Я код сам пишу! И если неполучается то... А какой код по-твоему может работать? Есть рабочий экземпляр? Я до покупки FIBPlus сжимал данные ZLib`ом и закидывал их в BLOB, но подобный фильтр,по-моему,намного удобнее будет.
Добавлено: 01 сен 2006, 09:23
Dimitry Sibiryakov
Ага, я уже догадался прочитать статью по ссылке. У тебя функция неправильно объявлена. Ей должен передаваться указатель на указатель на буфер. Т.е. примерно так:
Код: Выделить всё
PackBuffer(void *&SourceBuf,int &SourceLen)
Тогда должно заработать.
Добавлено: 01 сен 2006, 17:28
SAV
Dimitry Sibiryakov писал(а):Ага, я уже догадался прочитать статью по ссылке. У тебя функция неправильно объявлена. Ей должен передаваться указатель на указатель на буфер. Т.е. примерно так:
Код: Выделить всё
PackBuffer(void *&SourceBuf,int &SourceLen)
Тогда должно заработать.
Попробовал в более простом варианте:
void __fastcall PackBuffer(void *& SourceBuf,int &SourceLen)
{
try
{
free(SourceBuf); //Теперь вот так ругается:-( !!! BadParametr:a bad memory block 0x...... has been passed to the function.!!!!!
....
К чему приводить SourceBuf для функции free???
Добавлено: 04 сен 2006, 10:50
WildSery
Ну и зачем ты его освобождаешь? Буфер не освобождается, а возвращается назад.
Ты уже весь пример переврал...
Добавлено: 04 сен 2006, 23:59
SAV
WildSery писал(а):Ну и зачем ты его освобождаешь? Буфер не освобождается, а возвращается назад.
Ты уже весь пример переврал...
... попробовал по разному и realloc пробовал

Кто нибудь делал хоть какие нибудь Client BLOB-filters на C++, как вы меняли размер буфера???
p.s. Support из fibplus пока молчит, как быстро вообще они ответят?