| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Fortran > Переменные процедурного типа: есть ли такое в F90 |
| Автор: voytalexey 28.11.2011, 18:16 |
| Обычно работаю на Дельфи, а тут пришлось писать небольшую DLL на Compaq VF 6.5 И появился вопрос: есть ли возможность в фортране объявлять и использовать переменные процедурного типа? Делаю DLL с использованием IMSL, использую функцию вычисления интеграла: CALL DQDAGS (Fun1, ArrX(i-1), ArrX(i), 0.001, 0.001, integral, ERREST); Здесь первый параметр это имя функции. Таких функций у меня будет около десятка, все одной сигнатуры (как требует IMSL), но с разным содержанием. Вызов DQDAGS делается много раз внутри цикла. Не хочется делать внутри цикла монстру типа: if (i==1) then; CALL DQDAGS (Fun1, .....); endif; if (i==2) then; CALL DQDAGS (Fun2, .....); endif; ....................... if (i==10) then; CALL DQDAGS (Fun10, .....); endif; Хочется до цикла сдеать что-то типа: if (i==1) then; Fun=Fun1; endif; if (i==2) then; Fun=Fun2; endif; ....................... if (i==10) then; Fun=Fun10; endif; а внутри цикла вызывать CALL DQDAGS (Fun, .....); Можно ли такое в принципе сделать в Фортран90, и как объявить переменную "Fun" ? Че-то туплю, не могу в хелпе найти ни однозначно положительного, ни однозначно отрицательного ответа. Буду благодарен за любой аргументированный ответ, хоть положительный, хоть отрицательный. |
| Автор: FCM 30.11.2011, 15:46 | ||||
| В современном Фортране (F2003, F2008) для этого есть ссылки на процедуры. Такую ссылку можно прикреплять к разным процедурам и пользоваться ее именем вместо имени адресата. Но, если говорить о линейке Visual Fortran, к CVF6.5 это не относится. В рамках CVF можно попробовать целочисленные указатели:
Попробуй. Напиши, что получилось Возможно есть еще подходы - но что-то пока в голову ничего другого не идет. PS/ Если в IF-блоке одна инструкция, то вместо, например, можно проще
|
| Автор: voytalexey 1.12.2011, 15:21 | ||
| Попробовал вариант предложенный FCM, с небольшими изменениями, т.к. впрямую в проект DLL не переносится. На "живом" проекте выскакивала плавающая ошибка, сделал упрощённый модуль. Вот что получилось в тестовом модуле:
При проходе дебаггером видно что перед вызвовм call MyMegaFun(ADRESAT_OF_P,x,y) указатель P указывает куда надо, а вот величина ADRESAT_OF_P в окне просмотра локальных переменных равна нулю. Далее пошагово попадая внутрь "MyMegaFun" я вижу что переменные "x" и "y" имеют величину как и ожидается, а вот переменная "f" указывает куда-то в мусор, причем всегда в один и тот же, независимо от значения "ModelNo" и "P". Как следствие указателя в мусор, при выполнении строки "y=f(x);" вылетает AV. Вот такие результаты. |
| Автор: FCM 1.12.2011, 17:24 |
| Тот вариант, что я предложил, проверял на Intel Visual Fortran 12.1 - все работало. Gfortran тот вариант не поддержал. Видимо и CVF такой вариант неприемлет. Получили, что нестандартное расширение ведет себя "нестандартно" (не одинаково) . Стандартное (но уже в рамках F2003) решение подразумевает использование ссылок на процедуры - и поддерживается в Intel Fortran 12.1 и gfortran. Хотелось бы понять стратегию твоего изначального проекта. Действительно ли нужен динамический выбор интегрируемой функции? Интегрируемая функция должна где задаваться - в CVF или в Delfi? |
| Автор: BakinEugene 1.12.2011, 20:11 | ||
В программе, с которой я сейчас работаю, сделано так:
Но это написано на некой помеси 77 фортрана с 90, модули там не используются, и попытка распихать процедуры по модулям - рушит все это счастье. Зато компилируется и под Compaq и под gfortran. |