Форум: "Основная";
Текущий архив: 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.004 c