Compaq Visual Fortran 6.6,动态链接库(DLL)和模块

时间:2019-01-03 02:46:41

标签: dll module fortran fortran90

我需要使用Compaq Visual Fortran 6.6为Fortran应用程序创建和使用动态链接库(DLL)。以下代码可以正常工作:

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 :(得分:2)

您需要添加:

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

到模块,以便主程序可以从DLL中看到模块变量。否则,A,B和S是局部变量。

编辑:2019年1月16日

我能够登录到Bakhbergen的PC并最终找出问题所在。

在CVF 6.6C(和更高版本的Intel编译器)中,当您使用具有DLLEXPORT指令的模块时,它会变成DLLIMPORT,因此,我在上面提出了建议。但这并不总是这样,他拥有的版本也没有这种行为。在进行更改之前(我的记忆说过我曾游说过),您必须提供一个单独编译的.mod,其中源包含DLLIMPORT而不是DLLEXPORT。当我这样做时,该程序起作用了。我不记得是哪个更新进行了更改。

所以他要做的是拥有两个版本的MODUL2.f90,一个版本带有DLLEXPORT,另一个版本带有DLLIMPORT。 DLLEXPORT版本被内置到DLL中。链接主程序时,仅会编译(/ c)DLLIMPORT版本,而仅使用.mod而不使用.obj。我知道凌乱,这就是我们更改它的原因。