首页 > 解决方案 > 在 Fortran DLL 中调用 RANDOM_NUMBER

问题描述

我想在 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 中使用它们,我应该怎么做才能调用我的代码中的函数?

标签: fortrangfortrandllexport

解决方案


有两个主要问题导致 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 或更高版本,您可以指明将要导出的绑定名称

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 代码都应该在一个模块中,否则它将无法工作。


推荐阅读