Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.08.15;
Скачать: CL | DM;

Вниз

Delphi виснет   Найти похожие ветки 

 
Nostradamus ©   (2002-08-02 23:05) [0]

Запукаю прогу по дельфой и сразу закрываю - Delphi говорит что неможет остановить процесс или чё-то в этом роде и усё. Если потом отгружаю Делфи через Ctrl-Alt-Del виснет вся система. Причём никаких ошибок не выдаётся.
Я сначала думал из-за подружаемых длл - убрал все ображения к ним - всё равно виснет.
В OnCreate только инициализация переменных типа
fSmth := 0;
В OnDestroy:
Plr.Free;
Plr := nil;
Comp.Free;
Comp := nil;
Убирал всё что в OnDestroy - не помогло. Причём Plr и Comp не создаются в OnCreate.
Подскажите в чём проблема.


 
Слесарь Матерящийся   (2002-08-02 23:32) [1]

Это прога твоя виснет :) С Дельфёй всё ладушки


 
Nostradamus ©   (2002-08-02 23:48) [2]

Так главное если не из под Делфи запускать - не виснет!!!


 
Nostradamus ©   (2002-08-03 17:07) [3]

Ну мастера подскажите а то у меня уже рука устала Reset жать.


 
Юрий Зотов ©   (2002-08-03 17:22) [4]

Что тут подскажешь? Явно какие-то проблемы в программе, но информации слишком мало. Приведите хотя бы сообщение об ошибке (только точно и полностью, а не "че-то в этом роде"). Описание основного алгоритма программы тоже не помешает.


 
Nostradamus ©   (2002-08-03 17:48) [5]

Сообщение об ошибке нет, только если пытаю сделать Run -> Program Reset пишет: Timed out waiting for process to terminate.
На главной форме довольно много компонентов из не делфевских использую только RXGifAnimator.

procedure TMain.FormCreate(Sender: TObject);
begin
KnowProgAr[1] := ProgressBar1;
KnowProgAr[2] := ProgressBar2;
KnowProgAr[3] := ProgressBar3;
KnowProgAr[4] := ProgressBar4;
KnowProgAr[5] := ProgressBar5;
KnowProgAr[6] := ProgressBar6;
KnowProgAr[7] := ProgressBar7;
KnowProgAr[8] := ProgressBar8;
KnowProgAr[9] := ProgressBar9;
KnowProgAr[10] := ProgressBar10;

ActProgAr[0] := ProgressBar14;
ActProgAr[1] := ProgressBar15;
ActProgAr[2] := ProgressBar16;
ActProgAr[3] := ProgressBar17;
ActProgAr[4] := ProgressBar18;

CKLabAr[0] := Label0;
CKLabAr[1] := Label1;
CKLabAr[2] := Label2;
CKLabAr[3] := Label3;
CKLabAr[4] := Label4;
CKLabAr[5] := Label5;
CKLabAr[6] := Label6;
CKLabAr[7] := Label7;
CKLabAr[8] := Label8;
CKLabAr[9] := Label9;
CKLabAr[10] := Label10;

ActLabAr[0] := Label27;
ActLabAr[1] := Label28;
ActLabAr[2] := Label29;
ActLabAr[3] := Label30;
ActLabAr[4] := Label31;

Control1.ActivePageIndex := 0;
CompCtrl.ActivePageIndex := 0;

TrackBar1Change(self);

Control1.Enabled := False;
PowerBtn.Enabled := False;
ResetBtn.Enabled := False;
Pause1.Enabled := False;
end;

procedure TMain.FormDestroy(Sender: TObject);
begin
Plr.Free;
Comp.Free;
Plr := nil;
Comp := nil;
end;


 
Nostradamus ©   (2002-08-03 17:51) [6]

Главное дело виснет даже когда я только запускаю и сразу закрываю приложение. Да и ещё кое-что если ставлю breakpoint в OnDestroy и потом по F8 смотрю что там происходит - то прога нормально закрывается...


 
Юрий Зотов ©   (2002-08-03 17:58) [7]

А что делает программа? Ведь в ней, помимо Create и Destroy, наверное, и еще что-то имеется?

Есть ли в ней потоки? длительные по времени операции? и т.д.


 
Nostradamus ©   (2002-08-03 18:11) [8]

Эта такая себе игра логоческая. Потоков нет да и длинных по времени операций тоже нет. Собственно говоря она же виснет даже если её открыть и сразу закрыть так что кроме как код в ONCreate, OnDestry больше ничего не выполняется.
Статически подгружаю длл:

//external functions
//characters.dll
function GetCharList : PChar;
stdcall; external "CHARACTERS.DLL";
function GetProp(CharType, Num : SmallInt) : SmallInt;
stdcall; external "CHARACTERS.DLL";
function GetAnim(CharType : SmallInt) : PChar;
stdcall; external "CHARACTERS.DLL";
function GetDesc(CharType : SmallInt): PChar;
stdcall; external "CHARACTERS.DLL";
//bonus.dll
function GetBonusNames : PChar;
stdcall; external "BONUS.DLL";
function GetBonusProp(BonNum, PropType : SmallInt) : SmallInt;
stdcall; external "BONUS.DLL";
function GetBonDesc(BonNum : SmallInt) : PChar;
stdcall; external "BONUS.DLL";
//actions.dll
function GetActTypes : PChar;
stdcall; external "ACTIONS.DLL";
function GetActions(ActType : SmallInt) : PChar;
stdcall; external "ACTIONS.DLL";
procedure ExecuteAct(var Res : TResRec; ActName : PChar; ValInfo : PChar);
external "ACTIONS.DLL" name "ExecuteAction";
function GetParamsNeeded(ActName : PChar) : PChar;
stdcall; external "ACTIONS.DLL";
procedure MakePresentClear;
external "ACTIONS.DLL";

Ну больше незнаю даже что сказать. Подскажите хоть каким образом можно хоть эту проблему выявить.


 
Юрий Зотов ©   (2002-08-03 21:10) [9]

Есть одно подозрение, но надо проверить. Вы не могли бы привести код функции... ну, скажем, GetParamsNeeded и пример кода, вызывающего эту функцию?

Имеется в виду - где и как выделяется память для PChar и где и как она освобождается?


 
Nostradamus ©   (2002-08-03 21:46) [10]

Код где вызывается

S := GetParamsNeeded(PChar(ActList.Items[ActList.ItemIndex]));
P := Pos(";", S);
ResStr := "";
while Length(S) > 0 do begin
N1 := StrToInt(Copy(S, 1, P - 1));
case N1 of
0..8 : ResStr := ResStr + IntToStr(Plr.BonusPoints[N1]) + ";";
9 : ResStr := ResStr + IntToStr(Plr.Know[0]) + ";";
10 : ResStr := ResStr + IntToStr(MyTime) + ";";
end;
Delete(S, 1, P);
P := Pos(";", S);
end;

Код ф-ции в длл

function GetParamsNeeded(ActName : PChar) : PChar; stdcall;
var
I : Integer;
begin
Result := "";
for I := Low(ActAr) to High(ActAr) do
if ActAr[I] = ActName then begin
Result := PChar(ActNeedAr[I]);
Break;
end;
end;

А что для PChar обязательно память выделять надо?
Тогда это точно в этом ошибка.


 
Неотеничный Педоморф   (2002-08-03 23:34) [11]

Послушайте, если у вас dll, и в ней есть статические данные, инициализация которых происходит вне процедур/функций (и вне обработчика DLL_PROCESS_ATTACH), то приложение может виснуть при загрузке этой dll-ки (на LoadLibrary()).

Для полноценного зависания нужна Windows 9X.
На Windows 2000/XP ТАКИХ зависаний не наблюдалось.

Так что, может быть, надо прошерстить код в dll-ках, поместив ВЕСЬ инициализационный код в обработчик DLL_PROCESS_ATTACH?

Но, может быть, дело в другом... IMHO


 
Юрий Зотов ©   (2002-08-04 00:28) [12]

> Nostradamus © (03.08.02 21:46)

PChar - это просто указатель. По сути, типизированный Pointer. Указывает он на тело строки ASCIIZ - последовательность байтов, заканчивающуюся нулевым байтом.

Обычно используются статические переменные типа PChar и под них самих память выделять не нужно (если динамические - то, конечно, нужно, но такие конструкции (косвенная адресация) встречаются редко). А вот под то, на что PChar указывает - нужно.

Из этого, однако, не следует, что мы должны везде писать GetMem или что-то подобное. Если тело строки УЖЕ размещено в памяти, то ему можно просто присвоить адрес ее первого байта (или привести эту строку к PChar - тогда все сделает компилятор). Но вот если еще НЕ размещено, то память выделить нужно (иначе на что же он указывать будет?).

Теперь смотрим Ваш код в свете сказанного.

1. Вызов функции.

Насколько я понял, ActList - это TComboBox, или TListBox, или еще что-то в том же роде. Его строки уже размещены в памяти, поэтому приведение к PChar здесь вполне законно, ошибки нет.

2. Сама функция.

А вот здесь возможна ошибка. Я не знаю точно, как компилятор обработает оператор Result := "", но с формальной точки зрения это ошибка. Здесь надо выделить 1 байт, обнулить его, а его адрес занести в Result. А еще правильнее было бы написать Result := nil.

Возможно, компилятор Delphi настолько умен, что сам проделает все так, как нужно. Но это маловероятно. Поэтому, если условие в цикле выполнится хотя бы раз, то, скорее всего, функция сработает нормально. А если нет, то возможны неприятности.

Судя по большому количеству экспортируемых функций с параметрами или результатом типа PChar, подобные, или даже еще более опасные вещи возможны и в других местах. Последствия же этого могут быть разными и какое-нибудь Access Violation - еще не самое среди них плохое. Потому что хотя бы явно кричит об ошибке - а ведь ошибка может быть и скрытой. Похоже, что такая скрытая ошибка у Вас и возникла.

Если DLL используется только Дельфишными программами, то я бы посоветовал Вам вовсе отказаться от всяких PChar, а вместо них использовать обычный string. Для этого нужно в uses обоих проектов (DLL и EXE) прописать ShareMem (строго в самих DPR и строго самым первым). И не будет никакой головной боли с PChar, с выделением и освобождением памяти - все разрулит компилятор. А код станет даже проще.


 
Nostradamus ©   (2002-08-04 02:09) [13]

> Юрий Зотов

Во-первых огромное спасибо за такой подробный ответ.
О том что PChar - это поинтер я знал вообще-то и раньше, но всегда думал что компилятор автоматически выделяет памят для него причём ВСЕГДА. Оказывается был неправ... Значит если просто написать

var
S : PChar;
begin
//то сдесь сначала нужно выделить память
S := "something"; //я правильно понял???
end;

Сейчас попробую сделать как Вы посоветовали - надеюсь проблемы больше не будет.

> Неотеничный Педоморф
У меня dll статически подгружаются т.е. LoadLibrary я не использую


 
Nostradamus ©   (2002-08-04 05:25) [14]

Вот уже 3 часа пробую разные комбинации и ничего не получается. Сделал всё так как Вы сказали - ничего не изменилось :( (но зато теперь вроде с PChar-ом разобрался :) ). Очевидно проблема не в dll т.к. я пробывал убрать весь код относящийся к dll и всё равно после нескольких запусков - виснет. Можно было бы конечно так и оставить т.к. без Делфи прога не виснет, а под Дельфи только при выходе, но хочется всё таки разобраться в чём проблема.

Может ещё каки-нибудь идеи есть (извините за назойливость, но в будуйщем хочется это проблему больше не иметь).


 
Юрий Зотов ©   (2002-08-04 10:42) [15]

> я пробывал убрать весь код относящийся к dll и всё равно после нескольких запусков - виснет.

Да, тогда проблема, похоже, в чем-то другом. Попробуйте вот что.

В опциях проекта на вкладке Compiler выставьте Use debug DCUs, расставьте BreakPoint"ы в секциях финализации всех используемых модулей (включая стандартные модули VCL) и в деструкторах всех используемых классов (включая стандартные классы VCL). Затем пройдите этап завершения программы отладчиком.


> У меня dll статически подгружаются т.е. LoadLibrary я не использую

Статическая загрузка DLL отличается от динамической лишь тем, что LoadLibray и FreeLibrary пишем не мы, а компилятор (в начале и в конце программы соответственно). Поэтому они все равно есть (чудес не бывает - без подгрузки DLL ее не используешь), а код инициализации DLL и DLL_PROCESS_ATTACH/DETACH все равно отрабатывают. И поэтому постинг "Неотеничный Педоморф (03.08.02 23:34)" остается актуальным и при статическом связывании.


 
evgeg ©   (2002-08-04 11:10) [16]

> Nostradamus

У вас какая Windows? 95, 98?

Такая ситуация: отдельно программа запускается, из под Дельфи -- нет, похожа на нехватку системных ресурсов, которая случается под W95, W98, и НЕ случается под NT, 2000, XP.


 
Nostradamus ©   (2002-08-04 17:36) [17]

> Юрий Зотов
Спасибо. Сейчас буду дальше экспериментировать...

> evgeg

У меня именно Win98, только программа запускается в любом случае. Под Делфи она виснет при закрытии.


 
Извращенец ©   (2002-08-04 17:48) [18]

у меня та же проблема, то же сообщение, либо виснет, либо самому перегружать можно, но тока Ресет, тниче пишет что-то про процесс и не перегружает.


 
Юрий Зотов ©   (2002-08-04 17:56) [19]

Так что пишет-то?
Надо же точно говорить, а не "что-то про". Это все-таки программирование, а не гадание.



Страницы: 1 вся ветка

Текущий архив: 2002.08.15;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.016 c
1-48145
DeBuGeR
2002-07-31 20:05
2002.08.15
Баг в дельфи?


1-48153
lpp
2002-07-31 11:43
2002.08.15
Как сделать форму для ввода пароля?


14-48302
Пастор
2002-07-21 00:50
2002.08.15
Тест.. Какой компилятор круче ?


1-48049
dera
2002-08-04 09:06
2002.08.15
Как можно узнать раскладку клавы?


7-48342
boogier
2002-06-04 10:17
2002.08.15
Как получить путь к рабочему столу?