Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.006 c
1-48154
shubin
2002-08-01 14:18
2002.08.15
Нужен компонентик


1-48122
Night cold
2002-08-01 09:39
2002.08.15
DLL


4-48353
anod
2002-06-09 14:19
2002.08.15
TrackBar


3-47960
Vikuksa
2002-07-24 16:23
2002.08.15
ADO


1-48195
Evyshka
2002-08-02 15:54
2002.08.15
Kernel32.dll





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский