Topic: Fortran DLL for use in Excel VBA - another round of questions
Hi:
I am trying to use SimplyFortran to create a dll that is useable in Excel VBA, and perhaps also VB.NET in Visual Studio.
I looked at the discussion on 2013-11-11 and following days by rexxitall and Jeff's helpful comments.
When I copy and try to run Jeff's final types.dll example Excel will give me Run-time error '48':
File not found: c"\my-fortran\types.dll
And I get the same thing when I try my simpler example.
I don't seem to be able to register the dll, so I don't understand what is going wrong.
I assume I am missing something required to make a useable dll.
I am using the most recent version of SimplyFortran 2.15
My simple example is supposed to be a subroutine that takes two numbers and returns the addition, passing data types of double by reference. This dll works fine when called by Fortran programs, but not when using in Microsoft stuff like Excel VBA or Visual Studio VB.NET
The Fortran code is in a file called aplusb_sub.f90
Here is a paste of the code:
Subroutine apb(a,b,c)
use iso_c_binding, only: c_double
IMPLICIT NONE
!GCC$ attributes dllexport, stdcall :: apb
REAL(kind=c_double),INTENT(IN) :: a,b
REAL(kind=c_double),INTENT(OUT) :: c
c = a + b
END Subroutine
-----------------------------------------------------------------------------------------
Here is the makefile that is used to create the dll:
# Automagically generated by Approximatrix Simply Fortran 2.15
#
FC="C:\Program Files (x86)\Simply Fortran 2\mingw-w64\bin\gfortran.exe"
CC="C:\Program Files (x86)\Simply Fortran 2\mingw-w64\bin\gcc.exe"
AR="C:\Program Files (x86)\Simply Fortran 2\mingw-w64\bin\ar.exe"
WRC="C:\PROGRA~2\SIMPLY~1\MINGW-~1\bin\windres.exe"
RM=rm -f
IDIR=
# -I error: Directory C:\Users\cboardman\AppData\Local\\\sfpm\64\include does not exist
LDIR=
# -L error: Directory C:\Users\cboardman\AppData\Local\\\sfpm\64\lib does not exist
OPTFLAGS= -g
SPECIALFLAGS=$(IDIR)
RCFLAGS=-O coff
PRJ_FFLAGS=-fno-underscoring -fcheck=all
PRJ_CFLAGS=
PRJ_LFLAGS=-mrtd -static
FFLAGS=$(SPECIALFLAGS) $(OPTFLAGS) $(PRJ_FFLAGS) -Jmodules
CFLAGS=$(SPECIALFLAGS) $(OPTFLAGS) $(PRJ_CFLAGS)
"build\aplusb_sub.o": ".\aplusb_sub.f90"
$(FC) -c -o "build\aplusb_sub.o" $(FFLAGS) ".\aplusb_sub.f90"
clean: .SYMBOLIC
$(RM) "build\aplusb_sub.o"
$(RM) "apb.dll"
"apb.dll": "build\aplusb_sub.o"
$(FC) -o "apb.dll" -shared -Wl,--out-implib="apb.dll.a" -static "build\aplusb_sub.o" $(LDIR) $(PRJ_LFLAGS)
all: "apb.dll" .SYMBOLIC
-------------------------------------------------------------------------------------------
The build works and creates the apb.dll in my folder c:\my-fortran
Note that this folder is also in my PATH variable, and it is my primary location for my fortran programs.
And I can use this dll in a hello world type program:
program hello
use iso_c_binding, only: c_double
real(kind=c_double) :: a,b,c
real(kind=c_double) :: ansy
print *,"Hello World!"
a=3.3
b=8.1
Call apb(a,b,ansy)
print *, "from sub=", ansy
write(*,*)"Press Enter to Continue"
read(*,*)
end program hello
----------------------------------------------------------------------------------------------------------------
Now for the details on the Excel VBA. I have a module created to work with a macro-enabled spreadsheet (using Excel 2010).
I have the following Declare that tries to reference the dll
Declare Sub apb Lib "C:\my-fortran\apb.dll" Alias "apb@12" (ByRef a As Double, ByRef b As Double, ByRef c As Double)
I have tried this with and without the path to the dll. Both give me the error about not being able to find the dll
To exercise the dll I have created a public subroutine called Tryit, and I can run that from the Macros button. If you use it directly in a function you get the unhelpful error #Value! in the cell which references a function that calls the dll.
Here is the Tryit subroutine:
Public Sub Tryit()
Dim a, b, c As Double
a = 2.1
b = 3.2
Call VBdll.Addit(a, b, c)
MsgBox "addit " & c
'Call VBdll.Addit2(a, b, c)
Call apb(a, b, c)
MsgBox "apb " & c
End Sub
-----
In the first Addit function call I used a dll created by VB.NET and that works. It is a COM enabled dll created by Visual Studio.
But on the call to apb which is supposed to reference the Fortran dll, I get the Run-time error '48':
File not found c:\my-fortran\apb.dll
So, what do I need to do be enable that dll to work in Excel VBA? Or to fix it in some other way to make it useful.
The idea was to be able to create a much more complex subroutine in Fortran that takes multiple inputs and returns multiple outputs.
Thanks for any insight.
Regards
CR