Compaq Visual Fortran 6.6, библиотека динамических ссылок (DLL) и модуль - PullRequest
0 голосов
/ 03 января 2019

Мне нужно создать и использовать динамически подключаемую библиотеку (DLL) для приложения на Фортране, используя Compaq Visual Fortran 6.6.Следующий код работает просто отлично:

PROGRAM AMAIN1
IMPLICIT NONE
REAL(8):: A,B,S
A = 1D0
B = 2D0
CALL SUBRO1(A,B,S)
PRINT*, 'S = ', S
END PROGRAM AMAIN1

SUBROUTINE SUBRO1(A,B,S)
!DEC$ ATTRIBUTES DLLEXPORT :: SUBRO1
IMPLICIT NONE
REAL(8):: A,B,S
S = A + B
RETURN
END SUBROUTINE SUBRO1

Результат верный: S = 3.00000000000000 Нажмите любую клавишу для продолжения

Однако, если я реализую тот же алгоритм с помощью модуля, я получаю несогласованныерезультат (т. е. ноль):

PROGRAM AMAIN2
USE MODUL2
A = 1D0
B = 2D0
CALL SUBRO2
PRINT*, 'S = ', S
END PROGRAM AMAIN2

MODULE MODUL2
IMPLICIT NONE
REAL(8):: A,B,S
END MODULE MODUL2

SUBROUTINE SUBRO2
!DEC$ ATTRIBUTES DLLEXPORT :: SUBRO2
USE MODUL2
S = A + B
RETURN
END SUBROUTINE SUBRO2

Неверный результат: S = 0.000000000000000E + 000 Для продолжения нажмите любую клавишу

Как видно выше, DLL содержит только подпрограмму в обоих случаях(SUBRO1 и SUBRO2 соответственно).Я создал файлы DLL и LIB из визуальной среды разработки.Второй случай (с использованием модуля) представляет структуру моего большого исходного кода, поэтому мне нужно решить эту проблему.Любой совет будет принят с благодарностью.

Кстати, тот же алгоритм без использования DLL работает хорошо и дает правильный результат:

PROGRAM AMAIN3
USE MODUL3
A = 1D0
B = 2D0
CALL SUBRO3
PRINT*, 'S = ', S
END PROGRAM AMAIN3

MODULE MODUL3
IMPLICIT NONE
REAL(8):: A,B,S
END MODULE MODUL3

SUBROUTINE SUBRO3
USE MODUL3
S = A + B
RETURN
END SUBROUTINE SUBRO3

Результат правильный: S = 3.00000000000000 Нажмите любую клавишу, чтобыпродолжить

1 Ответ

0 голосов
/ 07 января 2019

Вам необходимо добавить:

!DEC$ ATTRIBUTES DLLEXPORT :: A,B,S

в модуль, чтобы основная программа могла видеть переменные модуля из DLL.В противном случае A, B и S являются локальными переменными.

Редактировать: 16 января 2019

Я смог войти на ПК Бахбергена и в конце концов выяснил проблему.

В CVF 6.6C (и более поздних компиляторах Intel), когда вы ИСПОЛЬЗУЕТЕ модуль, имеющий директиву DLLEXPORT, который превращается в DLLIMPORT, отсюда мой совет выше.Но так было не всегда, и у его версии такого поведения нет.Перед этим изменением (за которое моя память говорит, что я лоббировал) вы должны были предоставить отдельно скомпилированный .mod, где в источнике был DLLIMPORT вместо DLLEXPORT.Когда я это сделал, программа работала.Я не помню точно, какое обновление имело это изменение.

Так что ему нужно сделать, это иметь две версии MODUL2.f90, одну с DLLEXPORT и одну с DLLIMPORT.Версия DLLEXPORT встроена в DLL.Версия DLLIMPORT будет просто скомпилирована (/ c) и будет использоваться только .mod, а не obj при связывании основной программы.Грязный, я знаю, поэтому мы изменили его.

...