Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a gFortran dll with Excel 365 / VBA 7

For years I used a combination of dlls written in Fortran PowerStation and Excel 02/03, with VBA 6.

But progress marches on, and I got a new machine with Windows 64 bit, Excel 365 (64 bit), and no Fortran. So I downloaded gFortran as part of MinGW-w64-for 32 and 64 bit Windows from SourceForge. Now I have to get it working. Here is the Fortran source code, in a file called 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

(The second line specifies Microsoft attributes. More about this later.)

I compiled it as follows, from directory ., after adding the path to the MinGW bins added to %PATH%

gfortran -Wextra -Wall -pedantic -shared -fPIC -o .\Output\gTest.dll .\Source\gTest.F90

This produced no output, but did write the file gTest.dll.

And so onto Excel / VBA. I set up a little spread sheet, gTest.xlsm, which tried to invoke AddIt. It declared AddIt as follows:

Declare PtrSafe Function AddIt Lib "C:\A\Projects\gTest\Output\gTest.dll"(iVal1 As Integer, iVal2 As Integer) As Integer

No luck. So I entered the following VBA code and stepped through it:

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

As expected, it blew up on Sum =, with one of MS's more useless error messages "Error in loading DLL (Error 48)".

Now, I suspect that the problem is that I am not telling the dll what within it must be exported - the function of the MS attribute statement above. I see that in the C++ environment, you can export from a dll with either the keyword __declspec(dllexport), or with a module definition (.def) file. But I cannot see how you could utilise either of these with gFortran (and I have tried). Or, possibly, did I not compile and link for 64 bits?

Can someone please help me? It would be gratefully appreciated.

like image 893
Rogan Avatar asked Dec 07 '25 02:12

Rogan


1 Answers

!MS$ATTRIBUTES is ignored by gfortran, try

!GCC$ ATTRIBUTES DLLEXPORT

See https://gcc.gnu.org/onlinedocs/gfortran/ATTRIBUTES-directive.html

STDCALL is only relevant for 32 bit.

The alias can also be set using bind(C):

integer(2) function AddIt(iVal1,iVal2) bind(C, name='AddIt')

Please check that the kind numbers in MS Powerstation actually correspond to those in gfortran. Chances are that you actually want integer(8) or an equivalent using some more portable syntax Fortran: integer*4 vs integer(4) vs integer(kind=4)

like image 75
Vladimir F Героям слава Avatar answered Dec 08 '25 15:12

Vladimir F Героям слава



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!