Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.02.11;
Скачать: [xml.tar.bz2];

Вниз

Обработка исключительных ситуаций   Найти похожие ветки 

 
Abajun   (2002-01-28 13:39) [0]

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


 
Андрей Сенченко   (2002-01-28 13:43) [1]

try .. except
или
try .. finally

Судя по вопросу, скорее второе


 
Abajun   (2002-01-28 13:55) [2]

Так это все и написано:

try
Lvpp:= SomeFunction(a1,...);
except
Lvpp:= 100000;
end;

Иногда SomeFunction вылетает и программа дальше не идет, а хотелось, чтобы работал блок except. Как я понимаю, такой общий вид работает на все виды исключительных ситуаций. Так получается, что мой случай - это не такая ситуация?


 
Андрей Сенченко   (2002-01-28 14:00) [3]

Попробуй все-таки Finally. Лично я except-ом стараюсь не пользоваться. То ли он не понимает, что произошла исключительная ситуация, то ли я чего не то пишу, но если написано в Finally- работает, а если в Except - никак.


 
Abajun   (2002-01-28 14:04) [4]

Мне finally не подходит, т.к. этот блок выполняется обязательно, независимо от того, произошла ли ошибка или нет. А мне нужно в переменную Lvpp передать значение SomeFunction, а если в той какая-либо ошибка (не считает, например) - то присвоить значение 100000. Если функция вылетает - для меня это тоже результат.


 
MBo   (2002-01-28 14:18) [5]

если не разбираться в причинах, то можно по-тупому


try
Flag:=True;
Lvpp:= SomeFunction(a1,...);
flag:=False;
except
if Flag then
Lvpp:= 100000;
end;



 
Abajun   (2002-01-28 14:29) [6]

В строчке
Lvpp:= SomeFunction(a1,...)
программа заканчивает работу и ни на какой
flag:=False;
не пойдет.


 
MBo   (2002-01-28 14:31) [7]


ошибся

try
Flag:=True;
Lvpp:= SomeFunction(a1,...);
flag:=False;
finally
if Flag then
Lvpp:= 100000;
end;


 
Digitman   (2002-01-28 14:33) [8]

какое исключение возникает при выполнении вызова DLL-ф-ции ?


 
Abajun   (2002-01-28 14:48) [9]

А я не знаю - она просто вылетает и все. Кроме того, она вызывается и начинает считать, но в процессе выполнения что-то там не срабатывает (какие-то математические ошибки) и все.


 
Digitman   (2002-01-28 15:04) [10]

DLL "чужая" (без исх.текстов) или твоей разработки ?


 
Abajun   (2002-01-28 15:19) [11]

Исходники есть, но на Fortran (присоединяется через LoadLibrary).
Можно считать, что DLL закрыта.


 
Digitman   (2002-01-28 15:26) [12]

Импортировал правильно ? с соблюдением соглашений о связях с Fortran-кодом ?


 
Abajun   (2002-01-28 15:41) [13]

Все правильно. При некоторых сочетаниях фактических параметров функция считает и выдает результат, а при некоторых этот счет невозможен. Вот в последнем случае мне и необходимо переменной присвоить определенное число. Только "невозможность счета" - это вылет из функции.


 
Digitman   (2002-01-28 15:48) [14]

приведи декларацию импортируемой ф-ции и фрагмент кода ее вызова с декларацией всех факт.параметров


 
Abajun   (2002-01-28 16:00) [15]



type
TSub1 = function(a1,a2,a3,a4,a5,a6 : real) : real; stdcall;

var
Handle: THandle;
F4 : TSub1;
boolF4 : boolean;
Totn,G,GS,RG,m,Piv : real;

begin
...
boolF4:= false;
Handle := LoadLibrary("FortDLL-9.dll");
if Handle <> 0 then begin
@F4 := GetProcAddress(Handle,"LVPP");
if @F4 <> nil then boolF4:= true;
end;

...

Totn:= ...; G:= ...; GS:= ...; RG:= ...; m:= ...; Piv:= ...;
if boolF4 = true then
try
Lvpp:= F4(G,GS,RG,m,Totn,Piv);
except
Lvpp:= 100000;
end
else Lvpp:= 100000;

...

end;



 
Digitman   (2002-01-28 16:19) [16]

т.е., ты хочешь сказать, что объявление
Totn,G,GS,RG,m,Piv : real;
не меняется, а меняется лишь
Totn:= ...; G:= ...; GS:= ...; RG:= ...; m:= ...; Piv:= ...;

и при некоторой комбинации происходит сбой ?
еще раз - уверен ли ты, что декларация ф-ции достоверна ? может, один из параметров должен передаваться не по значению, а по ссылке ?


 
Abajun   (2002-01-28 16:24) [17]

Да. При некоторой комбинации переменных функция не считает. В этом случае в Lvpp нужно записать определенное число. Все декларации правильные и проверенные. Тем более в большинстве случаев функция вызывается и считает (правильно считает - проверено), а некоторых нет (что тоже нормальная ситуация). Просто мне надо, чтобы она не вылетала в

Lvpp:= F4(G,GS,RG,m,Totn,Piv);

а дальше продолжала работать.


 
MBo   (2002-01-28 16:29) [18]

обычно в fortran параметры передаются по ссылке (var)
кроме того, настораживает real - Delphi какие?
в новых по умолчанию real=double, но надежнее так и писать double.
Хотя, раз иногда работает верно -(и результат правильный?), то дело, вероятно, не в этом


 
MBo   (2002-01-28 16:30) [19]

а, пока писал - все ответили


 
Digitman   (2002-01-28 16:41) [20]

трассировать работу ф-ции в окне CPU не пытался ?


 
Digitman   (2002-01-28 16:45) [21]

Кстати, да, действительно упущенный (и оч.важный) момент ! <MBo> верно подсказывает, что в Fortran-подпрограммы факт.параметры должны передаваться по ссылке. Это и наводит на мысль, что декларация ф-ции неверна


 
Abajun   (2002-01-28 16:52) [22]

Все правильно передается - проверено много раз (могу в некоторых пределах менять dll - вставляю печать в файл переданных параметров). Все правильно в отдельных случаях считает. А в некоторых оно и не должно считать - это тоже правильно (я могу рассказать о сути задачи, если это улучшит понимание). Просто эти случаи надо отловить, но как?
Насчет CPU-окна я ничего не знаю.


 
Digitman   (2002-01-28 17:18) [23]

Ну-у-у, полезли в дебри) ...
Ты оспариваешь то факт, что соглашения о передаче факт.параметров в Fortran-подпрограмму предписывают передачу параметров по ссылке ? Или ты утверждаешь, что твоя DLL - Fortran-compatible, хотя на самом деле это может быть и не так ?

"А в некоторых оно и не должно считать" - это как понять ? кто это - "оно" ?

"Насчет CPU-окна я ничего не знаю" - печально, что ж тут сказать( ...


 
Abajun   (2002-01-28 17:38) [24]

Я ничего не оспариваю. Я просто говорю, что никаких нарушений по передаче параметров нет. Кстати, я могу и ошибаться, но директива stdcall, по-моему, означает передачу параметров по значению.
Извините, "оно" - это просто так. В смысле программа.
Хотелось просто узнать, можно ли как-то отловить непредвиденный выход из программы.
Или я что-то не так спрашиваю?


 
Иван Шихалев   (2002-01-28 17:42) [25]

Насколько я помню, при возникновении исключительной ситуации в DLL, вызывающая ее программа просто слетает (причем, DLL остается в памяти). Так что, видимо, придется лезть в Fortran и прописывать там нормальный выход вместо исключения.


 
Abajun   (2002-01-28 17:49) [26]

2 Иван Шихалев
Правильно - слетает. Значит в Делфи нельзя никак реализовать, чтобы не слетала?


 
Digitman   (2002-01-28 17:56) [27]

Директива stdcall отнюдь не означает способ передачи параметров, а означает она порядок их помещения в стек и указание Pascal-компилятору о том, что за баланс стека после завершения вызова ответственен сам вызываемый код. Вот и все. Но, кр.того, Fortran-п/программа ожидает, что переданные ей через стек в кач-ве факт.параметров величины являются не самими значениями, а указателями на адреса памяти, где эти значения хранятся.
Что делает ф-ция и что должна возвращать ?
Назначение параметров ?
Пример кода, когда передав ф-ции конкретные, определенные тобой и допустимые параметры, ты все же получил рез-т ее работы, соответствующий ожидаемому по описанию ф-ции ? Проверена ли правильность рез-та иными средствами (сказем, расчетами на обычном калькуляторе, если это возможно) ?


 
Abajun   (2002-01-28 18:10) [28]

2 Digitman
Почему тогда в хелпе по Фортрану написано, что

Calling Conventions for ATTRIBUTES Options

Default C STDCALL C,REFERENCE STDCALL,REFERENCE
Scalar Reference Value Value Reference Reference

Ну может, я что-то упустила.
Далее. Функция выполняет математические расчеты движения самолета и возвращает некоторое число - длину взлетно-посадочной полосы самолета. Параметры - это некоторые геометрические харак-ки самолета.
Перед вызовом функции им присваиваются определенные значения, например:
Totn:= 0,96; G:= 69,7; GS:= 570; RG:= 0,26; m:= 12,0; Piv:= 1,4;
В этом случае Lvpp = 3013,97.
При другом сочетании самолет просто не может полететь. Поэтому и функция не считает. Матмодель - не моя, редактировать ее мне сложно. Проверка осуществлялась на exe-шнике, из которого потом и переделывалась DLL.


 
Digitman   (2002-01-28 18:30) [29]

Функция НЕ МОЖЕТ НЕ СЧИТАТЬ ! В любом случае она обязана вернуть какой-либо результат, и , если вместо этого происходит непредусмотренный сбой в работе вызвающего ее кода, это говорит только об одном (при условии, что код вызываемой ф-ции отлажен) - неверно интерпретируются вх.параметры (если они есть) или неверно передается вых.результат.
Ну, я уж не знаю, что там может "не полететь" или "полететь не так, как хотелось бы", но - это факт.
Приведи тогда полный Паскаль-прототип библиотечных типов, где декларируется все, что экспортируется библиотекой. В том виде, как он тебе попал в руки (именно - источник первоначальной инф-ции об интерфейсе DLL), а не отредактированный уже тобой в процессе экспериментов. Будем сравнивать и анализировать.
В кр.случае, присылай саму DLL и всю док-цию, какой она сопровождается.


 
Abajun   (2002-01-28 18:42) [30]

Так в том и дело, что код не отлажен (как мне кажется). Тот кто писал саму программу на Fortrane, считает, что раз выдается ошибка (скорей всего математическая - деление на ноль и т.д.), программа вылетает - то значит этот случай неправильный. Меняются исходные данные - и все по новой. А у меня теперь из нее сделана DLL. Только такой вылет меня не устраивает. Так как на Делфи для меня было проще, то я решила обработать такую ситуацию здесь. Но теперь понимаю, что это практически невозможно, необходимо лезть в Фортран и там исправлять или матмодель (отлаживать), или обрабатывать исключения в DLL на Фортран.
Ладненько, спасибо большое за советы.


 
VictorT   (2002-01-29 10:31) [31]

Недавно сам столкнулся с подобной проблемой. Грабли оказались в том, что запускал програму из Дельфей (Run), а Дельфи отслеживает все исключительные ситуации (даже те, которые нормально обрабатываются), и прерывают програму с сообщением об этом, для продолжения роботы нужно нажать Run. Чтобы робота програмы не прерывалась, нужно её откомпилить и запускать полученый ЕХЕ-шник. Возможно, твоя проблема в этом.



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

Форум: "Основная";
Текущий архив: 2002.02.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.005 c
3-32138
dymka
2002-01-15 08:50
2002.02.11
TQuery без TDatabase


1-32274
чайничек
2002-01-27 09:50
2002.02.11
Переместить название одного узла (подузла) TTreeView в Edit или ComboBox


4-32381
_SnAke_
2001-12-08 16:00
2002.02.11
SystemTray


3-32130
Belov
2002-01-15 11:18
2002.02.11
Вопрос по связке DLL - БД


1-32260
pasha_64
2002-01-27 05:01
2002.02.11
Ввод в TMemo





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский