dll - Compaq Visual Fortran 6.6、动态链接库 (DLL) 和模块
问题描述
我需要使用 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 按任意键继续
解决方案
您需要添加:
!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 中。DLLIMPORT 版本只会被编译 (/c) 并且在链接主程序时只使用 .mod,而不是 ,obj。凌乱,我知道,这就是我们改变它的原因。
推荐阅读
- c# - 缺少 SHA256.HashData 方法?
- amazon-web-services - AWS codebuild 不支持 openjdk14?
- c# - C# AutoMapper Map来自两个不同的属性
- webpack - 如何修复 Chunk.modulesIterable 的弃用警告?
- java - java:如何确认数组已在数组操作菜单中创建
- arrays - Presto - 在列表中使用 serde?
- json - 从 JSON 解析创建简单结构
- mysql - MySQL查找包含相同字符串但不完全的行
- php - 调用未定义的方法 CodeIgniter\Database\MySQLi\Connection::like()
- javascript - 使用 useCallback 时如何记忆高阶函数?