在Fortran DLL中调用RANDOM_NUMBER



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

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 

这是我的VBA代码在Excel:

Private Declare PtrSafe Function randgf Lib "randgf.dll" () As Double
Public Function gfort_res() As Double
gfort_res = randgf()
End Function

如果我想在DLL中使用它们,我应该怎么做才能在代码中调用像RANDOM_NUMBER这样的函数?

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


其中之一,就是Excel找不到DLL文件,这是因为,即使dll文件是在同一文件夹的excel工作表,excel的进程当前目录不相同

对于这个问题,有两种可能的解决方案:

第一个:在函数声明中,您可以将DLL文件的完整路径:

Private Declare PtrSafe Function randgf Lib "C:myexcellibrandfuncrandgf.dll" () As Double

第二个:在调用函数之前,您可以将当前目录更改为dll文件夹:

Private Declare PtrSafe Function randgf Lib "randgf.dll" () As Double
Public Function gfort_res() As Double
ChDrive "C"
ChDir "myexcellibrandfunc"
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代码应该在一个模块内,否则它将无法工作。

我找到了这种行为的原因。在运行我的DLL之前,我必须将gfortran库复制到我的目标计算机。我只是将所有lib*.dll文件从mingw64bin目录复制到目标计算机的windowssystem32文件夹,现在dll工作正常,Excel返回所需的结果。

是否有任何方法自动加载所需的DLL从mingw64bin到我自己的DLL (randg . DLL)在编译和链接在我的源计算机?我想避免从mingw64bin中复制所有lib*.dll文件。

相关内容

  • 没有找到相关文章

最新更新