![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Не могу очистить буфер после компрессии методами Zlib
Alik © (2010-10-20 14:19:00)Добрый день,
Моя проблема заключается в том, что при очистке буфера сжатых данных после компрессии методами Zlib компилятор выдает ошибку.
Функция ZCompress помещена в DLL файл.
var
RawData: array of Byte; // исходный несжатый массив
CompressData: array of Byte; // конечный сжатый массив
RawDataLen: Integer; // размер несжатого массива
CompressedDataLen: Integer; // размер сжатого массива
begin
SetLength(RawData, RawDataLen);
...
RawData заполняется данными
...
ZCompress(@RawData[0],
RawDataLen,
Pointer(CompressedData),
CompressedDataLen,
zcMax);
//сохраняю сжатый массив
WriteFile(flw, CompressedData[0], CompressedDataLen, wtd, nil);
//пытаюсь убить сжатый файл
CompressedData := nil;
После чего появляется ошибка
end;
Модуль ShareMem подключен как в DLL так и в вызывающей программе.
_Юрий (2010-10-21 19:32:00) [1]
> GetMem(P1, RawDataLen);
> Move(RawData[0], P1^, RawDataLen);
> CompressBuf(P1,//@RawData[0],
как раз на вход то подавать дин. массив можно, главное - чтобы была заранее выделена необходимая длина.
> CompressedData := nil никаких проблем не возникает!!!
это вообще лишнее. Компилятор и так сообразит, что на массив больше ничего не указывает - по выходу за пределы области видимости переменной CompressedData
Leonid Troyanovsky (2010-10-20 21:50:00) [2]
> Alik (20.10.10 21:41) [12]
> Благодарю всех кто подключился к теме!
Тема любви к динамическим массивам (да еще и в длл)
не раскрыта.
--
Regards, LVT.
Leonid Troyanovsky (2010-10-20 21:44:00) [3]
> Alik (20.10.10 20:00) [9]
> * outBuffer = pointer (unallocated)
И с какого пуркуа совать туда динамический массив.
RTFM.
--
Regards, LVT.
Alik (2010-10-20 21:41:00) [4]Благодарю всех кто подключился к теме!
Проблема решилась следующим образом:
var
P1, P2: Pointer;
begin
....
try
GetMem(P1, RawDataLen);
Move(RawData[0], P1^, RawDataLen);
CompressBuf(P1,//@RawData[0],
RawDataLen,
P2,//Pointer(CompressedData),
CompressedDataLen);
SetLength(CompressedData, CompressedDataLen);
Move(P2^, CompressedData[0], CompressedDataLen);
finally
FreeMem(P1);
FreeMem(P2);
end;
И когда я вызываю
CompressedData := nil никаких проблем не возникает!!!
_Юрий (2010-10-20 20:11:00) [5]Дело в том, что память для динамического массива можно выделять только с помошью SetLength, иначе вы лишаете компилятор возможности корректно подсчитать ссылки и вовремя освободить память.
_Юрий (2010-10-20 20:06:00) [6]Попробуйте объявить CompressData как Pointer, и освобождайте память FreeMem'ом
Alik (2010-10-20 20:00:00) [7]
> Leonid Troyanovsky © (20.10.10 18:26) [8]
>
> > Alik (20.10.10 16:29) [7]
>
> > Проблема где то в другом, смотрите [4] и [6]
>
> Память для CompressData выделяет А.С. Пушкин?
>
> --
> Regards, LVT.
Память для CompressData выделяется в методе ZCompress библиотеке ZLib.
******************
* ZCompress *
* *
* pre-conditions *
* inBuffer = pointer to uncompressed data *
* inSize = size of inBuffer (bytes) *
* outBuffer = pointer (unallocated) *
* level = compression level *
* *
* post-conditions *
* outBuffer = pointer to compressed data (allocated) *
* outSize = size of outBuffer (bytes) *
*****************************************************************************}
Leonid Troyanovsky (2010-10-20 18:26:00) [8]
> Alik (20.10.10 16:29) [7]
> Проблема где то в другом, смотрите [4] и [6]
Память для CompressData выделяет А.С. Пушкин?
--
Regards, LVT.
Alik (2010-10-20 16:29:00) [9]
> Фокус_Ник (20.10.10 16:15) [5]
> > Alik (20.10.10 16:09) [4]
>
> Модуль ShareMem должен быть прописан САМЫМ ПЕРВЫМ в ОБОИХ
> dpr (и в exe, и в dll). Похоже, что у Вас это не так.
Да они прописаны и там и там первыми, проверил!
Проблема где то в другом, смотрите [4] и [6]
Alik (2010-10-20 16:27:00) [10]Подключил стандартную библиотеку ZLib в Delphi 7.
Как только очищаю сжатый массив появляется та же самая ошибка. Если отключаю очистку, потом ошибка появляется где то по ходу выполнения программы. То есть налицо какой то глюк в памяти, а где именно он возникает?
Может я не правильно задаю буффера?
RawData: array of Byte; // исходный несжатый массив
CompressData: array of Byte; // конечный сжатый массив
RawDataLen: Integer; // размер несжатого массива
CompressedDataLen: Integer; // размер сжатого массива
try
CompressBuf(@RawData[0],
RawDataLen,
Pointer(CompressedData),
CompressedDataLen);
finally
RawData := nil;
CompressedData := nil;
end
При том при этом я вижу сжатые данные, по ним вопросов нет!
Фокус_Ник (2010-10-20 16:15:00) [11]> Alik (20.10.10 16:09) [4]
Модуль ShareMem должен быть прописан САМЫМ ПЕРВЫМ в ОБОИХ dpr (и в exe, и в dll). Похоже, что у Вас это не так.
Alik (2010-10-20 16:09:00) [12]
> Palladin © (20.10.10 14:22) [1]
>
> > Модуль ShareMem подключен как в DLL так и в вызывающей
> программе.
>
> самым первым? в dpr?
Так как проблема осталась, подключил сам модель напрямую, т.е. вызов функции сжатия осуществляется изнутри программы. Тем не менее ошибка возникает при каждом вызове функции.
Alik (2010-10-20 15:21:00) [13]Проблема все таки возникает при вызове CompressedData := nil,
но не каждый раз.
???
Alik (2010-10-20 14:42:00) [14]
> Palladin © (20.10.10 14:22) [1]
>
> > Модуль ShareMem подключен как в DLL так и в вызывающей
> программе.
>
> самым первым? в dpr?
Благодарю Вас, вопрос решен, ShareMem был прописан в юните, где вызывалось сжатие.
Прописал в dpr все работат!)
Palladin (2010-10-20 14:22:00) [15]
> Модуль ShareMem подключен как в DLL так и в вызывающей программе.
самым первым? в dpr?