Форум: "Основная";
Текущий архив: 2002.08.15;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.007 c