From: aeroguy on
A BIG thank you to every one who responded to this post.


I have successfuly managed to pass an array to fortran dll using intel
fortran compiler. nOw on to the amin programming :)


Here's the full code (that works) for everyone's reference!!


Cheers!!



Fortran Code
*************

Subroutine FortranDLL(Array1, upbound )
!DEC$ ATTRIBUTES DLLEXPORT,DECORATE, ALIAS: 'FORTRANDLL' :: FortranDLL
!DEC$ ATTRIBUTES REFERENCE :: Array1
!DEC$ ATTRIBUTES REFERENCE :: upbound
Implicit None
! ...argument declarations
Integer :: upbound
Integer :: Array1(1:upbound)


Integer :: i

open(10,file="c:\temp\temp.txt")
write(10,*) ' hi'
close(10)

do i=1,upbound
Array1(i)=Array1(i)+10
end do

End Subroutine FortranDLL


Don't forget to set this settings in Intel Visual Fortran

Project/Settings/Fortran/External Procedures/Calling convention ->
STDCALL (/iface:stdcall)

Excel VBA
*************


Declare Sub FortranDLL Lib "C:\TEMP\FcallA.dll" Alias
"FORTRANDLL" (ByRef Array1 As Long, ByRef upbound As Long)

Option Base 1

Sub CommandButton1_Click()

Dim II As Long
Dim test(1 To 5) As Long


For I = 1 To 5
test(I) = I
Next I

II = 5
Call FortranDLL(test(1), II)


Range("a2").Value = test(1)
Range("a3").Value = test(2)
Range("a4").Value = test(3)
Range("a5").Value = test(4)
Range("a6").Value = test(5)


End Sub





From: James Van Buskirk on
"aeroguy" <sukhbinder.singh(a)gmail.com> wrote in message
news:330bdafb-08f1-4fc4-ab5f-615ed146f9eb(a)m7g2000prd.googlegroups.com...

>A BIG thank you to every one who responded to this post.

> Subroutine FortranDLL(Array1, upbound )
> !DEC$ ATTRIBUTES DLLEXPORT,DECORATE, ALIAS: 'FORTRANDLL' :: FortranDLL
> !DEC$ ATTRIBUTES REFERENCE :: Array1
> !DEC$ ATTRIBUTES REFERENCE :: upbound
> Implicit None
> ! ...argument declarations
> Integer :: upbound
> Integer :: Array1(1:upbound)

Why the celebration? Doesn't this mean you have to write a separate
copy of your DLL for each compiler? Intel doesn't permit mixing
bind(C) with STDCALL, but I'm not sure about the reason. Initially
there was this issue about hidden LEN arguments for string arguments
and function results, but that was just a misunderstanding on Intel's
part and has been fixed. What is the blocking issue now?

gfortran is IIRC horribly broken as regards -mrtd and that switch
just isn't viable for any nontrivial application. Your test for
gfortran was therefore trivial. Try another test where the STDCALL
procedure does something like invoke BESSEL_J0 in a loop to see if
gfortran is generating STDCALL references of a CDECL procedure.

And isn't Microsoft trying to kill off VBA anyway and replace it
with something worse? It seems with each generation of software,
the vendors try to make your old skills worthless and require you
to learn a whole new interface to the same program. I saw
someone's Windows Explorer in Windows 7 the other day and there
was no obvious way to get it out of the execrable icon view where
all the files are scattered randomly in 2-d to the list view where
you can order them so as to see the most recent files at the end of
the list. The only way I could read the directory was to copy it
onto a thumb drive and plug it into my aging xp-x64 box.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


From: Luka Djigas on
On Thu, 10 Dec 2009 11:23:49 -0700, "James Van Buskirk"
<not_valid(a)comcast.net> wrote:

>
>And isn't Microsoft trying to kill off VBA anyway and replace it
>with something worse?

Yes, VSTA I believe it's called ... although I think VBA will still be
here in at least one more version. Autodesk's abandoning it too (going
back to lisp basics).




pp, Luka
From: user1 on
James Van Buskirk wrote:
> "aeroguy" <sukhbinder.singh(a)gmail.com> wrote in message
>
>
> gfortran is IIRC horribly broken as regards -mrtd and that switch
> just isn't viable for any nontrivial application. Your test for
> gfortran was therefore trivial.

OK. It doesn't "decorate" names in a manner consistent with calls to the
Windows API. Does that mean that non-trivial programs must call the
Windows API ?


>> Try another test where the STDCALL
>> procedure does something like invoke BESSEL_J0 in a loop to see if
>> gfortran is generating STDCALL references of a CDECL procedure.


OK. Let's try it. You may note that I am equally awkward with Fortran
and VBA.

Subroutine FortranDLL( Array1, upbound )
Integer upbound
Double Precision Array1(upbound)
xinc=.1
do i=1,upbound
x=besj0(xinc*i)
Array1(i)=x
end do
End Subroutine FortranDLL

compiled as before

gfortran -mrtd -fno-underscoring -shared -o fortrandll.dll fortrandll.f90


tested with VBA code

Declare Sub fortrandll Lib "C:\TEMP\fortrandll.dll" (ByRef Array1 As
Double, ByRef upbound As Long)

Sub Button1_Click()
Dim II As Long
Dim test(10) As Double
II = 11
Call fortrandll(test(1), II)
Range("a1").Value = test(1)
Range("a2").Value = test(2)
Range("a3").Value = test(3)
Range("a4").Value = test(4)
Range("a5").Value = test(5)
Range("a6").Value = test(6)
Range("a7").Value = test(7)
Range("a8").Value = test(8)
Range("a9").Value = test(9)
Range("a10").Value = test(10)
End Sub

And, when I click button1, the following ten values pop into the spreadsheet

0.997501552
0.990024984
0.977626264
0.960398197
0.938469827
0.912004828
0.88120091
0.84628737
0.807523787
0.765197694

It seems to work. I suppose, if a stack is not being cleaned properly,
it might take more than ten calls to besj0 before something gets clobbered.










From: Tobias Burnus on
On 12/10/2009 11:51 PM, user1 wrote:
> James Van Buskirk wrote:
>> "aeroguy" <sukhbinder.singh(a)gmail.com> wrote in message
>>
>> gfortran is IIRC horribly broken as regards -mrtd and that switch
>> just isn't viable for any nontrivial application. Your test for
>> gfortran was therefore trivial.

I agree that -mrtd should not be used. At it only was shortly mentioned
by James, I want to add the following: gfortran supports since GCC 4.5
attributes which can be used to set the calling convention. See
http://gcc.gnu.org/onlinedocs/gfortran/GNU-Fortran-Compiler-Directives.html

Note: As James already regretted, the Intel compiler's directives
(!DEC$) do not work [well?, at all?] with BIND(C), while gfortran's
directives do not offer all functionality, relying on BIND(C) for the
rest. Consequently, one needs to write different interfaces for gfortran
and ifort. (How do other Fortran compilers for Windows handle this?)

For C binding, see your favorite Fortran 2003 book or have a look at
http://gcc.gnu.org/onlinedocs/gfortran/Interoperability-with-C.html

(Comments to that section of the gfortran manual [but also to the rest
of the manual or to gfortran in general] are welcome.)

Tobias