fortran - 在 Fortran DLL 中调用 RANDOM_NUMBER

标签 fortran gfortran dllexport

我想在 Windows 中使用 gfortran (mingw - 64bit) 从 Fortran 代码编译和链接动态链接库 (dll)。我在 Excel 64 位中测试生成的 dll。我注意到,对于以下 Fortran 代码,Excel 没有返回任何结果(它返回:#VALUE!):

Function RANDGF()  bind(c)
use ISO_C_BINDING
implicit none
!GCC$ ATTRIBUTES DLLEXPORT :: RANDGF
Double Precision  :: RANDGF
Double Precision  :: A

Call RANDOM_NUMBER(A)
RANDGF = 2.0
END
但是,如果我评论 Call RANDOM_NUMBER(A)行,DLL 返回预期结果。
我用于编译的命令是:
gfortran -shared -fpic -o randgf.dll randgf.f90 
这是我在 Excel 中的 VBA 代码:
Private Declare PtrSafe Function randgf Lib "randgf.dll" () As Double
Public Function gfort_res() As Double
   gfort_res = randgf()
End Function
我应该怎么做才能调用像 RANDOM_NUMBER 这样的函数在我的代码中,如果我想在 DLL 中使用它们?

最佳答案

有两个主要问题导致 Excel 不执行该函数:

其中之一是 Excel 找不到 DLL 文件,这是因为,
即使 dll 文件在 Excel 工作表的同一文件夹中,Excel 的
进程当前目录不一样。
对于这个问题,有两种可能的解决方案:
第一:在函数声明处,你可以把DLL文件的完整路径:

Private Declare PtrSafe Function randgf Lib "C:\myexcellib\randfunc\randgf.dll" () As Double
第二:在调用该函数之前,可以将当前目录更改为dll文件夹:
Private Declare PtrSafe Function randgf Lib "randgf.dll" () As Double
Public Function gfort_res() As Double
   ChDrive "C"
   ChDir "\myexcellib\randfunc"
   gfort_res = randgf()
End Function

第二个问题是Excel在DLL文件中找不到函数。
对于这个问题,也有两种可能的解决方案:
第一:您可以在声明中将函数的序号表示为“别名”
子句(例如,如果序数为 1):
Private Declare PtrSafe Function RANDFG Lib "randfg.dll" Alias "#1" () As Double
第二:如果你使用的是fortran 2003或更高版本,可以注明绑定(bind)姓名 那会
导出:
function RANDGF()  bind(c, name="RANDGF")
  use ISO_C_BINDING
  implicit none
  !GCC$ ATTRIBUTES DLLEXPORT :: RANDGF
  Double Precision  :: RANDGF
  Double Precision  :: A

  call RANDOM_NUMBER(A)
end function RANDGF

重要 : 所有的 VBA 代码都应该在一个 Module 内,否则它不会工作。

关于fortran - 在 Fortran DLL 中调用 RANDOM_NUMBER,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69160361/

相关文章:

Fortran:将任意 "structures"传递给模块子例程

fortran - 为什么 'use mpi' 使用 mpif90 失败

windows - "Can' t open module file 'types.mod' "when compiling a main.f90 program

c - SHGetPathFromIDList函数为什么导出了3次

fortran - Fortran 有哪些可视化库?

fortran - 使用延迟长度字符串读取用户输入

arrays - 在连续编译之间更快地从硬盘读取数据的技巧

C++ 如何在 def 文件中指定命名空间

c++ - 内联和 dlimport/dllexport

variables - Fortran 编译器术语 : Dummy Variables and Attributes