【发布时间】:2021-11-27 15:56:00
【问题描述】:
多年来,我使用了用 Fortran PowerStation 和 Excel 02/03 编写的 dll 与 VBA 6 的组合。
但进步在继续,我得到了一台新机器,它装有 Windows 64 位、Excel 365(64 位),但没有 Fortran。所以我从 SourceForge 下载了 gFortran 作为 MinGW-w64-for 32 和 64 位 Windows 的一部分。 现在我必须让它工作。 这是 Fortran 源代码,位于名为 gTest.F90 的文件中:
integer(2) function AddIt(iVal1,iVal2)
!MS$ATTRIBUTES dllexport, stdcall, alias:'AddIt' :: ADDIT
Integer(2) iVal1,iVal2
AddIt=iVal1+iVal2
end function AddIt
(第二行指定 Microsoft 属性。稍后会详细介绍。)
在添加到添加到 %PATH% 的 MinGW 箱的路径后,我从目录 . 编译如下
gfortran -Wextra -Wall -pedantic -shared -fPIC -o .\Output\gTest.dll .\Source\gTest.F90
这没有产生任何输出,但确实写入了文件 gTest.dll。
等等到 Excel / VBA。我设置了一个小电子表格 gTest.xlsm,它试图调用 AddIt。它声明 AddIt 如下:
Declare PtrSafe Function AddIt Lib "C:\A\Projects\gTest\Output\gTest.dll"(iVal1 As Integer, iVal2 As Integer) As Integer
没有运气。于是我输入了以下 VBA 代码并单步执行:
Sub RunIt()
Dim Val1 As Integer, Val2 As Integer, Sum As Integer
Val1 = 1
Val2 = 10
Sum = AddIt(Val1, Val2)
Debug.Print Val1, Val2, Sum
End Sub
正如预期的那样,它在 Sum = 上爆炸了,出现了 MS 更无用的错误消息之一"Error in loading DLL (Error 48)"。
现在,我怀疑问题在于我没有告诉 dll 必须导出其中的内容 - 上面的 MS 属性语句的功能。我看到在 C++ 环境中,您可以使用关键字 __declspec(dllexport) 或模块定义 (.def) 文件从 dll 导出。但是我看不出您如何将其中任何一个与 gFortran 一起使用(我已经尝试过)。
或者,可能,我没有为 64 位编译和链接?
有人可以帮我吗?将不胜感激。
【问题讨论】:
-
最好明确地将
ByRef放在函数参数上,这样可以清楚地看出值是通过引用而不是值传递的。然后检查用作编译器选项的调用约定,以查看参数何时应作为引用以及何时作为值。
标签: excel vba fortran gfortran dllexport