Calling fortran dll from visual basic 
Author Message
 Calling fortran dll from visual basic

Here is a simple example to supplement Steve's comments:

If all you need is to read the array in the fortran DLL the easiest way to
do it is pass the first element of the array:

dim n as long, m as long
dim myarray(10,10) as single
m=10
n=10
...
call mydllsub(myarray(1,1),n,m)

the declare statement should look like:

Declare Sub mydllsub lib "mydll.dll" (byref firstelement as single, byref n
as long, byref m as long)

where n and m are the dimensions of the array. On the fortran side, declare
your argument as:

subroutine mydllsub(myarray,n,m)
integer::n,m
real::myarray(n,m)

There are three more things you need to take care of:

1) The calling convention: i.e. you need to tell the Fortran compiler that
the subroutine is to use the STDCALL convention
2) Possibly the name mangling of subroutine mydllsub introduced by the
Fortran compiler.
3) Tell the compiler to export mydllsub to the DLL (from your post, I assume
you already know how to do this).

If you are using CVF, then just add the following to the declaration of
mydllsub:

!DEC$ATTRIBUTES STDCALL:: mydllsub
!DEC$ATTRIBUTES DLLEXPORT:: mydllsub
!DEC$ATTRIBUTES ALIAS: 'mydllsub'::mydllsub
!DEC$ATTRIBUTES REFERENCE:: myarray,n,m

If you are using a different compiler, you can find information (and
examples) of how to do (1), (2) and (3) in our web site (check
www.canaimasoft.com/OnlineManuals/UserManual/default.htm, in particular
chapter 5, which covers three of the major Fortran compilers; CVF, Lahey and
Absoft).

best regards,

--
Marco A. Garcia
Canaima Software
P.O. Box 13162
La Jolla, CA. 92039
U.S.A.

Tel/Fax: (619) 233-6831
http://www.*-*-*.com/
Developers of f90SQL the Database Connectivity Solution for Fortran, and
f90VB the library for seamless Fortran-VB and Fortran-OLE Automation
integration


Quote:
> This seems to be a very problem laden area. I can pass real and integer
> but I'm having big problems passing real*4 arrays. From what debugging I
> can do I am finding completely absurd values in each array element
> inside the dll. I am even finding an integer has silly values. One thing
> I have noticed is that the array elements appear to alternate as
> enormous and tiny values, could the 32 bit words be 2 bytes offset in
> memory by any chance?

> I am passing everything byref AND reemphasise the fact inside the dll. I
> am also (for the moment) using fixed length arrays, both similarly
> dimensioned. Finally I have checked a million times that the passed
> arguments are all the correct datatype and appear in the right position.

> Can anyone point me to really good help, or offer it?

> I have tried to look at the fortran faq but my browser complains its
> unavailable, or cant open it. Brief desriptions are on the www but there
> are no really good examples of the VB and Fortran code.
> thanks
> gary



Wed, 03 Sep 2003 01:03:15 GMT  
 Calling fortran dll from visual basic
Hi Gary,

What fortran compiler are you using ?  Each one is different
in this matter.  I use Watcom F77 and I actually put a C DLL
between the VB code and the F77 code just to iron these
addressing issues out.

Works just fine for me as I have such complicated constructs as:

Declare Sub CalculateIsothermalFlash Lib "DII2VBAS.DLL" _

   (ByVal NumberOfInletStreams As Long, _
    ByVal NumberOfOutletStreams As Long, _
    ByVal NumberOfComponents As Long, _
    ByVal padtodouble As Long, _
    InletStreamTemperatures As Double, _
    InletStreamPressures As Double, _
    InletStreamMolarFlowrates As Double, _
    InletStreamMolarFlowratesByComponent As Double, _
    OutletStreamVaporFractions As Double, _
    OutletStreamTemperatures As Double, _
    OutletStreamPressures As Double, _
    OutletStreamEnthalpies As Double, _
    OutletStreamMolarFlowrates As Double, _
    OutletStreamMolarFlowratesByComponent As Double)

   CalculateIsothermalFlash Nin, Nout3, Ncomp, padtodouble, _
                   InletStreamTemperature(0), _
                   InletStreamPressure(0), InletStreamMolarFlowrate(0), _
                   InletStreamMolarFlowrateByComponent(0), _
                   OutletStreamVaporFraction(0), _
                   OutletStreamTemperature(0), _
                   OutletStreamPressure(0), OutletStreamEnthalpy(0), _
                   OutletStreamMolarFlowrate(0), _
                   OutletStreamMolarFlowrateByComponent(0)

Thanks,
Lynn McGuire



Wed, 03 Sep 2003 02:53:29 GMT  
 Calling fortran dll from visual basic
I gave an invalid in my previous post. The write address is:

http://www.canaimasoft.com/f90VB/OnlineManuals/UserManual/default.htm

regards,

--
Marco A. Garcia
Canaima Software



Quote:
> Here is a simple example to supplement Steve's comments:

> If all you need is to read the array in the fortran DLL the easiest way to
> do it is pass the first element of the array:

> dim n as long, m as long
> dim myarray(10,10) as single
> m=10
> n=10
> ...
> call mydllsub(myarray(1,1),n,m)

> the declare statement should look like:

> Declare Sub mydllsub lib "mydll.dll" (byref firstelement as single, byref
n
> as long, byref m as long)

> where n and m are the dimensions of the array. On the fortran side,
declare
> your argument as:

> subroutine mydllsub(myarray,n,m)
> integer::n,m
> real::myarray(n,m)

> There are three more things you need to take care of:

> 1) The calling convention: i.e. you need to tell the Fortran compiler that
> the subroutine is to use the STDCALL convention
> 2) Possibly the name mangling of subroutine mydllsub introduced by the
> Fortran compiler.
> 3) Tell the compiler to export mydllsub to the DLL (from your post, I
assume
> you already know how to do this).

> If you are using CVF, then just add the following to the declaration of
> mydllsub:

> !DEC$ATTRIBUTES STDCALL:: mydllsub
> !DEC$ATTRIBUTES DLLEXPORT:: mydllsub
> !DEC$ATTRIBUTES ALIAS: 'mydllsub'::mydllsub
> !DEC$ATTRIBUTES REFERENCE:: myarray,n,m

> If you are using a different compiler, you can find information (and
> examples) of how to do (1), (2) and (3) in our web site (check
> www.canaimasoft.com/OnlineManuals/UserManual/default.htm, in particular
> chapter 5, which covers three of the major Fortran compilers; CVF, Lahey
and
> Absoft).

> best regards,

> --
> Marco A. Garcia
> Canaima Software
> P.O. Box 13162
> La Jolla, CA. 92039
> U.S.A.

> Tel/Fax: (619) 233-6831
> http://www.canaimasoft.com
> Developers of f90SQL the Database Connectivity Solution for Fortran, and
> f90VB the library for seamless Fortran-VB and Fortran-OLE Automation
> integration



> > This seems to be a very problem laden area. I can pass real and integer
> > but I'm having big problems passing real*4 arrays. From what debugging I
> > can do I am finding completely absurd values in each array element
> > inside the dll. I am even finding an integer has silly values. One thing
> > I have noticed is that the array elements appear to alternate as
> > enormous and tiny values, could the 32 bit words be 2 bytes offset in
> > memory by any chance?

> > I am passing everything byref AND reemphasise the fact inside the dll. I
> > am also (for the moment) using fixed length arrays, both similarly
> > dimensioned. Finally I have checked a million times that the passed
> > arguments are all the correct datatype and appear in the right position.

> > Can anyone point me to really good help, or offer it?

> > I have tried to look at the fortran faq but my browser complains its
> > unavailable, or cant open it. Brief desriptions are on the www but there
> > are no really good examples of the VB and Fortran code.
> > thanks
> > gary



Wed, 03 Sep 2003 03:19:27 GMT  
 Calling fortran dll from visual basic
Also note that you can only pass one dimension
arrays from VB to Fotran due to VB's safe arrays.

If you need multiple dimensions then just do the
old  ((x -1) * rows + y) thing.

Thanks,
Lynn



Wed, 03 Sep 2003 15:50:46 GMT  
 Calling fortran dll from visual basic
On Fri, 16 Mar 2001 12:02:52 +0000, gary

Quote:

>This seems to be a very problem laden area. I can pass real and integer
>but I'm having big problems passing real*4 arrays. From what debugging I
>can do I am finding completely absurd values in each array element
>inside the dll. I am even finding an integer has silly values. One thing
>I have noticed is that the array elements appear to alternate as
>enormous and tiny values, could the 32 bit words be 2 bytes offset in
>memory by any chance?

>I am passing everything byref AND reemphasise the fact inside the dll. I
>am also (for the moment) using fixed length arrays, both similarly
>dimensioned. Finally I have checked a million times that the passed
>arguments are all the correct datatype and appear in the right position.

>Can anyone point me to really good help, or offer it?

>I have tried to look at the fortran faq but my browser complains its
>unavailable, or cant open it. Brief desriptions are on the www but there
>are no really good examples of the VB and Fortran code.

Visual Basic passes arrays using a "SafeArray" descriptor, which most
(if not all) Fortran compilers don't understand directly.  The easiest
workaround is to pass the first element of the array (if I recall
correctly, this would be A(0)) instead of the whole array.  VB will
pass this element by reference, and the Fortran code can treat it as
an array.

If you want to get into decoding the descriptor, that takes more work.
Compaq Visual Fortran provides a module (DFCOM) with routines for
manipulating SafeArray descriptors.  You can also look at Canaima
Software's f90VB library - http://www.canaimasoft.com/f90vb/



Fortran Engineering
Compaq Computer Corporation, Nashua NH

Compaq Fortran web site: http://www.compaq.com/fortran
Message Board: http://www.compaq.com/fortran/forum



Tue, 02 Sep 2003 22:23:24 GMT  
 Calling fortran dll from visual basic
This seems to be a very problem laden area. I can pass real and integer
but I'm having big problems passing real*4 arrays. From what debugging I
can do I am finding completely absurd values in each array element
inside the dll. I am even finding an integer has silly values. One thing
I have noticed is that the array elements appear to alternate as
enormous and tiny values, could the 32 bit words be 2 bytes offset in
memory by any chance?

I am passing everything byref AND reemphasise the fact inside the dll. I
am also (for the moment) using fixed length arrays, both similarly
dimensioned. Finally I have checked a million times that the passed
arguments are all the correct datatype and appear in the right position.

Can anyone point me to really good help, or offer it?

I have tried to look at the fortran faq but my browser complains its
unavailable, or cant open it. Brief desriptions are on the www but there
are no really good examples of the VB and Fortran code.
thanks
gary



Tue, 02 Sep 2003 20:02:52 GMT  
 Calling fortran dll from visual basic
Hi Marco,

A small correction to the fine example.  Absent an "Option Base 1",
the shape of myarray is (11, 11), so n and m should each be assigned
11 instead of 10.  
I always declare VB arrays like so, myarray(1 To 10, 1 To 10) to avoid
confusion and cases of "cut and paste" editing where the Option Base
doesn't get copied too.

Cheers,
John

On Fri, 16 Mar 2001 21:33:15 +0430, "Marco A. Garcia"

Quote:

>Here is a simple example to supplement Steve's comments:

>If all you need is to read the array in the fortran DLL the easiest way to
>do it is pass the first element of the array:

>dim n as long, m as long
>dim myarray(10,10) as single
>m=10
>n=10
>...
>call mydllsub(myarray(1,1),n,m)

>the declare statement should look like:

>Declare Sub mydllsub lib "mydll.dll" (byref firstelement as single, byref n
>as long, byref m as long)

>where n and m are the dimensions of the array. On the fortran side, declare
>your argument as:

>subroutine mydllsub(myarray,n,m)
>integer::n,m
>real::myarray(n,m)

>There are three more things you need to take care of:

>1) The calling convention: i.e. you need to tell the Fortran compiler that
>the subroutine is to use the STDCALL convention
>2) Possibly the name mangling of subroutine mydllsub introduced by the
>Fortran compiler.
>3) Tell the compiler to export mydllsub to the DLL (from your post, I assume
>you already know how to do this).

>If you are using CVF, then just add the following to the declaration of
>mydllsub:

>!DEC$ATTRIBUTES STDCALL:: mydllsub
>!DEC$ATTRIBUTES DLLEXPORT:: mydllsub
>!DEC$ATTRIBUTES ALIAS: 'mydllsub'::mydllsub
>!DEC$ATTRIBUTES REFERENCE:: myarray,n,m

>If you are using a different compiler, you can find information (and
>examples) of how to do (1), (2) and (3) in our web site (check
>www.canaimasoft.com/OnlineManuals/UserManual/default.htm, in particular
>chapter 5, which covers three of the major Fortran compilers; CVF, Lahey and
>Absoft).

>best regards,



Thu, 04 Sep 2003 22:08:08 GMT  
 Calling fortran dll from visual basic
Hi,

There is no need to resort to using SafeArrays for passing multi
dimension arrays from VB to fortran.  See Marco's post earlier in this
thread for an example.  

-John



Quote:
>Also note that you can only pass one dimension
>arrays from VB to Fotran due to VB's safe arrays.

>If you need multiple dimensions then just do the
>old  ((x -1) * rows + y) thing.

>Thanks,
>Lynn



Thu, 04 Sep 2003 22:10:26 GMT  
 Calling fortran dll from visual basic
Thanks for all your advice - but unfortunately still no luck. I guess there could be  a
really stupid simple thing I am overlooking. My fortran code is as follows:
---------------------------------------------------------------
subroutine r0g(n,angles,amps,r0,g)
! specify that the routine name is to be made available to callers
!
!dec$ attributes dllexport :: r0g
!dec$ attributes alias:'r0g' :: r0g
!dec$ attributes stdcall :: r0g

integer*4 n
real*4 r0
real*4 g
real*4 amps(10)
real*4 angles(10)

real*4 a(2,2),b(2),f(2)

pi=acos(-1.)
open(unit=1,file='d:\data\gary\debug.txt',status='new',iostat=ier)
write(1,*) 'n=',n
write(1,*) ((angles(j)),j=1,n)
write(1,*) 'amps(1-n)'
write(1,*) ((amps(j)),j=1,n)
close(1)
.......
return
end
--------------------------------------------------
The VB for excel is as follows:
--------------------------------------------------
Declare Sub r0g Lib "d:\data\gary\excel code\r0g\r0g\debug\r0g.dll" (n, angles, amps, r0, g)
'r0g.dll must be accessible in the "path"
Option Base 1
Dim n As Long
Dim angles(10) As Single
Dim amps(10) As Single
Dim r0 As Single
Dim g As Single
Dim r0_or_g As String * 1
Function r0_g(angles, amps, r0_or_g) As Single
'
' function callable from excel for least squares fit of amplitudes
'
' do some parameter checks
'
n1 = get_dim(angles)
n2 = get_dim(amps)
If (n1 <> n2) Then
    par_err ("different number of angles and amps")
    GoTo 999
End If
r0_or_g = LCase(r0_or_g)
If ((r0_or_g <> "r") And (r0_or_g <> "g")) Then
    par_err ("'r0_or_g' must be either 'r' or 'g'")
    GoTo 999
End If
n = n2
' call fortran dll
r0g n, angles(1), amps(1), r0, g
' return the desired result
If (r0_or_g = "r") Then
    r0_g = r0
Else
    r0_g = g
End If
999:
End Function
------------------------------------------------------------
The values of the arguments passed to the dll are correct when debugged in VB. The dump
(snipped) from the debugging write statements inside the dll is as follows:
------------------------------------------------------------
n=       16387
 angles(1-n)
  1.2611686E-44  0.0000000E+00  9.2165440E-38  0.0000000E+00  4.2038954E-45
  0.0000000E+00  4.2038954E-45  0.0000000E+00  2.8025969E-45  0.0000000E+00
  2.2040533E-39  0.0000000E+00  4.2038954E-45  0.0000000E+00  4.2038954E-45
  0.0000000E+00  0.0000000E+00  1.7257719E-39  2.2944076E-39  0.0000000E+00
  8.2651947E-40  0.0000000E+00  1.7247406E-39  4.5499385E+22  4.8799092E+22
 -1.9431448E+07  2.3109808E-39  2.2942955E-39  0.0000000E+00  2.4615321E-39
......
amps(1-n)
  1.2611686E-44  0.0000000E+00  9.2166247E-38  0.0000000E+00  2.2964479E-41
  0.0000000E+00  2.2433331E-39  0.0000000E+00  2.2963078E-41  0.0000000E+00
  2.2433275E-39  0.0000000E+00  2.8025969E-45  0.0000000E+00  1.4012985E-45
  0.0000000E+00  0.0000000E+00  1.2611686E-44  0.0000000E+00  9.2165440E-38
  0.0000000E+00  4.2038954E-45  0.0000000E+00  4.2038954E-45  0.0000000E+00
......
------------------------------------------------------------
You can see that n is arriving in the dll as some humongous number. Its like its not picking
up the correct referenced memory location. Consequently the dll runs off the end of the
arrays. Any help would be appreciated.

BTW my fortran compiler is COMPAQ DVF.

Thanks
Gary


writes

Quote:
>John,

etc...


Fri, 05 Sep 2003 20:19:13 GMT  
 Calling fortran dll from visual basic


| Thanks for all your advice - but unfortunately still no luck. I guess
there could be  a
| really stupid simple thing I am overlooking. My fortran code is as
follows:

When you use !DEC$ATTRIBUTES STDCALL, it also implies that
args are passed ByVal by default, where applicable (i.e.
for scalar values). Either add a ByVal for n in VB or
!DEC$ATTRIBUTES REFERENCE:: N in Fortran and it should be OK.
It is usually a good idea when mixing languages to explicitly
declare ByVal/ByRef for all arguments, to prevent situations like
the one you have.

Jugoslav



Fri, 05 Sep 2003 21:46:30 GMT  
 Calling fortran dll from visual basic
You should take a peek at the documentation for the declare statement.
http://msdn.microsoft.com/library/default.asp?URL=/library/officedev/...

Without a type specifier for the argumements to your dll routine, the
default is Variant type.  Not a good match for your fortran
declarations. ;)  
Interesting, the variables you're declaring (n, angles, amps, ...)
look like module level variables.  If that's purposeful, be careful of
local variables of the same name hiding the scope of the globals.

Here's some suggested changes:

Fortran
-------
 - Remove the stdcall attribute.  In this example, it's not buying you
anything extra and it has the side effect of changing the semantics to
pass by value which you'd have to explicitly change for the dummy args
using the reference attribute (the alias statement takes care of the
forced lower-case v. upper case issue).

 - change the declaration of amps and angles to use the size passed in
dummy argument n:
integer :: n
real :: amps(n), angles(n)

VB
---
 - Change the Declare statement to include the type of the args:

Declare Sub r0g Lib "...\r0g.dll" (n as Long, angles as Single, amps
as Single, r0 as Single, g as Single)

feel free to explicitly use ByRef as Jugoslav suggested if you'd like

I won't comment on the globals since I don't have enough context to do
so.

That should get you going.  Post back with changes if not.

hth,
John

On Mon, 19 Mar 2001 12:19:13 +0000, gary

Quote:

>Thanks for all your advice - but unfortunately still no luck. I guess there could be  a
>really stupid simple thing I am overlooking. My fortran code is as follows:
>---------------------------------------------------------------
>subroutine r0g(n,angles,amps,r0,g)
>! specify that the routine name is to be made available to callers
>!
>!dec$ attributes dllexport :: r0g
>!dec$ attributes alias:'r0g' :: r0g
>!dec$ attributes stdcall :: r0g

>integer*4 n
>real*4 r0
>real*4 g
>real*4 amps(10)
>real*4 angles(10)

>real*4 a(2,2),b(2),f(2)

>pi=acos(-1.)
>open(unit=1,file='d:\data\gary\debug.txt',status='new',iostat=ier)
>write(1,*) 'n=',n
>write(1,*) ((angles(j)),j=1,n)
>write(1,*) 'amps(1-n)'
>write(1,*) ((amps(j)),j=1,n)
>close(1)
>.......
>return
>end
>--------------------------------------------------
>The VB for excel is as follows:
>--------------------------------------------------
>Declare Sub r0g Lib "d:\data\gary\excel code\r0g\r0g\debug\r0g.dll" (n, angles, amps, r0, g)
>'r0g.dll must be accessible in the "path"
>Option Base 1
>Dim n As Long
>Dim angles(10) As Single
>Dim amps(10) As Single
>Dim r0 As Single
>Dim g As Single
>Dim r0_or_g As String * 1
>Function r0_g(angles, amps, r0_or_g) As Single
>'
>' function callable from excel for least squares fit of amplitudes
>'
>' do some parameter checks
>'
>n1 = get_dim(angles)
>n2 = get_dim(amps)
>If (n1 <> n2) Then
>    par_err ("different number of angles and amps")
>    GoTo 999
>End If
>r0_or_g = LCase(r0_or_g)
>If ((r0_or_g <> "r") And (r0_or_g <> "g")) Then
>    par_err ("'r0_or_g' must be either 'r' or 'g'")
>    GoTo 999
>End If
>n = n2
>' call fortran dll
>r0g n, angles(1), amps(1), r0, g
>' return the desired result
>If (r0_or_g = "r") Then
>    r0_g = r0
>Else
>    r0_g = g
>End If
>999:
>End Function
>------------------------------------------------------------
>The values of the arguments passed to the dll are correct when debugged in VB. The dump
>(snipped) from the debugging write statements inside the dll is as follows:
>------------------------------------------------------------
>n=       16387
> angles(1-n)
>  1.2611686E-44  0.0000000E+00  9.2165440E-38  0.0000000E+00  4.2038954E-45
>  0.0000000E+00  4.2038954E-45  0.0000000E+00  2.8025969E-45  0.0000000E+00
>  2.2040533E-39  0.0000000E+00  4.2038954E-45  0.0000000E+00  4.2038954E-45
>  0.0000000E+00  0.0000000E+00  1.7257719E-39  2.2944076E-39  0.0000000E+00
>  8.2651947E-40  0.0000000E+00  1.7247406E-39  4.5499385E+22  4.8799092E+22
> -1.9431448E+07  2.3109808E-39  2.2942955E-39  0.0000000E+00  2.4615321E-39
>......
>amps(1-n)
>  1.2611686E-44  0.0000000E+00  9.2166247E-38  0.0000000E+00  2.2964479E-41
>  0.0000000E+00  2.2433331E-39  0.0000000E+00  2.2963078E-41  0.0000000E+00
>  2.2433275E-39  0.0000000E+00  2.8025969E-45  0.0000000E+00  1.4012985E-45
>  0.0000000E+00  0.0000000E+00  1.2611686E-44  0.0000000E+00  9.2165440E-38
>  0.0000000E+00  4.2038954E-45  0.0000000E+00  4.2038954E-45  0.0000000E+00
>......
>------------------------------------------------------------
>You can see that n is arriving in the dll as some humongous number. Its like its not picking
>up the correct referenced memory location. Consequently the dll runs off the end of the
>arrays. Any help would be appreciated.

>BTW my fortran compiler is COMPAQ DVF.

>Thanks
>Gary


>writes
>>John,

>etc...



Sat, 06 Sep 2003 05:20:52 GMT  
 
 [ 11 post ] 

 Relevant Pages 

1. Calling Fortran DLL in VIsual Basic 6.0

2. Calling Fortran-DLLs with Visual Basic 4.0

3. Creating - Fortran 77 dll for use in Visual Basic 6.0 (not using Compaq Visual Fortran)

4. HELP : Visual Basic calling FORTRAN DLL

5. HELP : visual basic calling fortran DLL

6. Setting up a MS Fortran .DLL/calling from Visual Basic

7. Calling Fortran 77 dll's from Visual Basic under Excel

8. Visual Basic call a Fortran DLL

9. Calling a Visual Basic DLL from a Fortran executable

10. Calling MS Excel Visual Basic functions from Fortran DLL

11. Calling a fortran DLL from Visual Basic

12. compag visual fortran dll callable from visual basic 6

 

 
Powered by phpBB® Forum Software