![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Exception при закрытии проги
SpellCaster © (2006-10-02 19:05:00)Возникла такая проблема: моя программа при закрытии выдает исключение EInvalidPointer. Схема работы проги такая:
1) статически линкуется ДЛЛ
2) создается указатель на Double, выделяется память под него
3) вызывается функция из ДЛЛ, параметром ей передается этот указатель. Там он заполняется числами и возвращается назад.
4) здесь по идее с этими числами что-то делаем
5) освобождаем память, занятую буфером - в OnClose формы
всё.
На освобождении памяти и происходит исключение. Если его убрать и/или присвоить указателю nil, исключение отодвигается до момента закрытия проги. Как его там отследить, я не знаю - присвоение OnException не действует, т.к. никаких объектов уже к этому моменту нет.
Чем это может быть вызвано и как от этой ерунды избавиться? Указатель я передаю как константу, он нигде не меняется.
Или скажите хотя бы, как спрятать этот эксепшн, чтобы не мешался.
SpellCaster (2006-10-03 10:49:00) [1]Всё, проблема решена. Сорри, мой косяк - не выделялось достаточно памяти под буфер.
SpellCaster (2006-10-03 10:39:00) [2]jack128
Там не одна переменная, а много, причём сколько, заранее неизвестно.
Описание функций в длл:
procedure Init; stdcall;
procedure SetParameters(const pSatNames, pStatNames: PChar); stdcall;
function GetData(var Time: Integer; const Buffer: PDouble): Integer; stdcall;
Код последней функции:
function GetData(var Time: Integer; const Buffer: PDouble): Integer; stdcall;
var st,sat,msr,t: Integer;
s: string;
begin
if not RightInit then Error('GetLib.dll: Не было инициализации!');
try
try
// здесь мы просто заполняем буфер инкрементальными значениями
for t:=0 to StatCnt*SatCnt*MsrCnt-1 do
begin
PDouble(Integer(Buffer)+t*sizeof(Double))^:=t;
end;
on e: exception do
Error('Ошибка: '+E.Message);
end;
finally
client.Close; // это объект сокета, он создается, но пока не используется
end;
end;
Прототипы в проге:
procedure Init; stdcall; external 'GetLib.dll'
procedure SetParameters(const pSatNames, pStatNames: PChar); stdcall; external 'GetLib.dll'
function GetData(var Time: Integer; const Buffer: PDouble): Integer; stdcall; external 'GetLib.dll'
Код вызова процедур из длл:
procedure TForm1.Button1Click(Sender: TObject);
var t,i,j,k,st,sat,msr: Integer;
begin
Init;
SetParameters(PChar(Edit2.Text),PChar(Edit1.Text));
if GetData(t,buf)<0 then begin memo1.Lines.Add('ошибка при соединении'); exit; end;
for st:=0 to StatCnt-1 do
for sat:=0 to SatCnt-1 do
for msr:=0 to MsrCnt-1 do
begin
memo1.Lines.Add(floattostr(Get3DArrayVal(Buf,st,sat,msr))); // эта функция позволяет обращаться с буфером как с трехмерным массивом
end;
end;
Ещё одна странность в том, что в отладчике, ставя точку останова внутри этой функции и просматривая память по адресу Buffer, вижу одни нули. Это связано с тем, что у длл и проги разные адресные пространства? Но ведь заполнение буфера происходит нормально, и процедура в проге выводит ряд увеличивающихся чисел.
icWasya (2006-10-03 09:31:00) [3]Для начала покажи прототипы функции в DLL и в программе. Наверняка что-нибудь не то с соглашениями о вызове.
guav (2006-10-02 19:54:00) [4]Код dll можно привести ?
jack128 (2006-10-02 19:18:00) [5]SpellCaster (02.10.06 19:05)
2) создается указатель на Double, выделяется память под него
3) вызывается функция из ДЛЛ, параметром ей передается этот указатель. Там он заполняется числами и возвращается назад.
4) здесь по идее с этими числами что-то делаем
а просто объявить переменную var D: Double; и передать @D в dll не судьба???