- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello all,
I'm just returning to Fortran after a long sojourn. I have some f90 code that I am trying to wrap in a dll so I can call it from elsewhere. I'm having trouble getting everything to hang together.
In the example I include below I have a single exported function that is simply a wrapper for another function:
REAL*8 FUNCTION CylinderModel( R, Theta, Incl, Decl, Intensity, Radius, Depth_Top, Depth_Bottom )
!
!DEC$ ATTRIBUTES C, reference, ALIAS:"CylinderModel", DLLEXPORT::CylinderModel
! Variables
IMPLICIT NONE
INTERFACE
REAL*8 FUNCTION CYLNDR(I_T, A, H, I_0, D_0, R, THETA, Z)
REAL*8 I_T ! Total magnetization (remanent plus induced)
REAL*8 A ! Radius of the cylinder
REAL*8 H ! Height of the cylinder
REAL*8 I_0, D_0 ! Inclination and declination of the earth's field
REAL*8 I_P, D_P ! Inclination and declination of the polarization
REAL*8 R,THETA,Z ! Evaluation point of the field w.r.t top of cylinder
end FUNCTION
end interface
INTEGER*4 Cells
REAL*8 CellSize
REAL*8 Incl, Decl, Intensity, Radius, Depth_Top, Depth_Bottom
REAL*8 R, Theta
REAL*8 Cylndr
! Body of CylinderMode
CylinderModel = CYLNDR(Intensity,Radius,Depth_Bottom,Incl,Decl,R,Theta,Depth_Top)
end Function CylinderModel
REAL*8 FUNCTION CYLNDR(I_T, A, H, I_0, D_0, R, THETA, Z)
IMPLICIT NONE
INTERFACE
REAL*8 FUNCTION INFCYL(I_T, A, I_0, D_0, I_P, D_P, R, THETA, Z)
REAL*8 I_T ! Total magnetization (remanent plus induced)
REAL*8 A ! Radius of the cylinder
REAL*8 I_0, D_0 ! Inclination and declination of the earth's field
REAL*8 I_P, D_P ! Inclination and declination of the polarization
REAL*8 R,THETA,Z ! Evaluation point of the field w.r.t top of cylinder
end function
end interface
! Formal Parameters:
REAL*8 I_T ! Total magnetization (remanent plus induced)
REAL*8 A ! Radius of the cylinder
REAL*8 H ! Height of the cylinder
REAL*8 I_0, D_0 ! Inclination and declination of the earth's field
REAL*8 I_P, D_P ! Inclination and declination of the polarization
REAL*8 R,THETA,Z ! Evaluation point of the field w.r.t top of cylinder
REAL*8 ZABS
!We are assuming no remanent magnetization
I_P = I_0
D_P = D_0
ZABS = ABS(Z)
IF(H.LT.0) THEN
CYLNDR = INFCYL(I_T, A, I_0, D_0, I_P, D_P, R, THETA, ZABS)
ELSE
CYLNDR = INFCYL(I_T, A, I_0, D_0, I_P, D_P, R, THETA, ZABS) &
& -INFCYL(I_T, A, I_0, D_0, I_P, D_P, R, THETA, ZABS+H)
ENDIF
RETURN
END
I am getting the following compile time errors with this code:
Z:\Fortran\FGoldak\Cylinder.f90(29): error #6409: This name has already been used as an external procedure name. [CYLNDR]
REAL*8 Cylndr
---------^
Z:\Fortran\FGoldak\Cylinder.f90(32): error #7977: The type of the function reference does not match the type of the function definition. [CYLNDR]
CylinderModel = CYLNDR(Intensity,Radius,Depth_Bottom,Incl,Decl,R,Theta,Depth_Top)
^
Z:\Fortran\FGoldak\Cylinder.f90(32): error #8000: There is a conflict between local interface block and external interface block. [CYLNDR]
CylinderModel = CYLNDR(Intensity,Radius,Depth_Bottom,Incl,Decl,R,Theta,Depth_Top)
--------------------^
and so on...
Inititally the sub functions were just defined as variables like this:
REAL*8 CYLNDR etc.. but that didn't compile either
Compiling with Intel Visual Fortran 11.0.072 [IA-32]...
ifort /nologo /Od /gen-interfaces /warn:interfaces /module:"Debug\" /object:"Debug\" /traceback /check:bounds /libs:dll /threads /dbglibs /c /Qvc8 /Qlocation,link,"C:\Program Files\Microsoft Visual Studio 8\VC\bin" "Z:\Fortran\FGoldak\Cylinder.f90"
Z:\Fortran\FGoldak\Cylinder.f90(30): error #6418: This name has already been assigned a data type. [CYLNDR]
REAL*8 CYLNDR
---------^
Z:\Fortran\FGoldak\Cylinder.f90(32): error #7977: The type of the function reference does not match the type of the function definition. [CYLNDR]
CylinderModel = CYLNDR(Intensity,Radius,Depth_Bottom,Incl,Decl,R,Theta,Depth_Top)
^
Z:\Fortran\FGoldak\Cylinder.f90(32): error #6633: The type of the actual argument differs from the type of the dummy argument. [INTENSITY]
CylinderModel = CYLNDR(Intensity,Radius,Depth_Bottom,Incl,Decl,R,Theta,Depth_Top)
------------------------^
I'm sure its a simple thing but I've been reading and banging my head on this for 2 days.
HOW do I declare a function so that it can be called from elsewhere in the same file??
thanks
Marc Pelletier
Goldak Airborne Surveys
I'm just returning to Fortran after a long sojourn. I have some f90 code that I am trying to wrap in a dll so I can call it from elsewhere. I'm having trouble getting everything to hang together.
In the example I include below I have a single exported function that is simply a wrapper for another function:
REAL*8 FUNCTION CylinderModel( R, Theta, Incl, Decl, Intensity, Radius, Depth_Top, Depth_Bottom )
!
!DEC$ ATTRIBUTES C, reference, ALIAS:"CylinderModel", DLLEXPORT::CylinderModel
! Variables
IMPLICIT NONE
INTERFACE
REAL*8 FUNCTION CYLNDR(I_T, A, H, I_0, D_0, R, THETA, Z)
REAL*8 I_T ! Total magnetization (remanent plus induced)
REAL*8 A ! Radius of the cylinder
REAL*8 H ! Height of the cylinder
REAL*8 I_0, D_0 ! Inclination and declination of the earth's field
REAL*8 I_P, D_P ! Inclination and declination of the polarization
REAL*8 R,THETA,Z ! Evaluation point of the field w.r.t top of cylinder
end FUNCTION
end interface
INTEGER*4 Cells
REAL*8 CellSize
REAL*8 Incl, Decl, Intensity, Radius, Depth_Top, Depth_Bottom
REAL*8 R, Theta
REAL*8 Cylndr
! Body of CylinderMode
CylinderModel = CYLNDR(Intensity,Radius,Depth_Bottom,Incl,Decl,R,Theta,Depth_Top)
end Function CylinderModel
REAL*8 FUNCTION CYLNDR(I_T, A, H, I_0, D_0, R, THETA, Z)
IMPLICIT NONE
INTERFACE
REAL*8 FUNCTION INFCYL(I_T, A, I_0, D_0, I_P, D_P, R, THETA, Z)
REAL*8 I_T ! Total magnetization (remanent plus induced)
REAL*8 A ! Radius of the cylinder
REAL*8 I_0, D_0 ! Inclination and declination of the earth's field
REAL*8 I_P, D_P ! Inclination and declination of the polarization
REAL*8 R,THETA,Z ! Evaluation point of the field w.r.t top of cylinder
end function
end interface
! Formal Parameters:
REAL*8 I_T ! Total magnetization (remanent plus induced)
REAL*8 A ! Radius of the cylinder
REAL*8 H ! Height of the cylinder
REAL*8 I_0, D_0 ! Inclination and declination of the earth's field
REAL*8 I_P, D_P ! Inclination and declination of the polarization
REAL*8 R,THETA,Z ! Evaluation point of the field w.r.t top of cylinder
REAL*8 ZABS
!We are assuming no remanent magnetization
I_P = I_0
D_P = D_0
ZABS = ABS(Z)
IF(H.LT.0) THEN
CYLNDR = INFCYL(I_T, A, I_0, D_0, I_P, D_P, R, THETA, ZABS)
ELSE
CYLNDR = INFCYL(I_T, A, I_0, D_0, I_P, D_P, R, THETA, ZABS) &
& -INFCYL(I_T, A, I_0, D_0, I_P, D_P, R, THETA, ZABS+H)
ENDIF
RETURN
END
I am getting the following compile time errors with this code:
Z:\Fortran\FGoldak\Cylinder.f90(29): error #6409: This name has already been used as an external procedure name. [CYLNDR]
REAL*8 Cylndr
---------^
Z:\Fortran\FGoldak\Cylinder.f90(32): error #7977: The type of the function reference does not match the type of the function definition. [CYLNDR]
CylinderModel = CYLNDR(Intensity,Radius,Depth_Bottom,Incl,Decl,R,Theta,Depth_Top)
^
Z:\Fortran\FGoldak\Cylinder.f90(32): error #8000: There is a conflict between local interface block and external interface block. [CYLNDR]
CylinderModel = CYLNDR(Intensity,Radius,Depth_Bottom,Incl,Decl,R,Theta,Depth_Top)
--------------------^
and so on...
Inititally the sub functions were just defined as variables like this:
REAL*8 CYLNDR etc.. but that didn't compile either
Compiling with Intel Visual Fortran 11.0.072 [IA-32]...
ifort /nologo /Od /gen-interfaces /warn:interfaces /module:"Debug\" /object:"Debug\" /traceback /check:bounds /libs:dll /threads /dbglibs /c /Qvc8 /Qlocation,link,"C:\Program Files\Microsoft Visual Studio 8\VC\bin" "Z:\Fortran\FGoldak\Cylinder.f90"
Z:\Fortran\FGoldak\Cylinder.f90(30): error #6418: This name has already been assigned a data type. [CYLNDR]
REAL*8 CYLNDR
---------^
Z:\Fortran\FGoldak\Cylinder.f90(32): error #7977: The type of the function reference does not match the type of the function definition. [CYLNDR]
CylinderModel = CYLNDR(Intensity,Radius,Depth_Bottom,Incl,Decl,R,Theta,Depth_Top)
^
Z:\Fortran\FGoldak\Cylinder.f90(32): error #6633: The type of the actual argument differs from the type of the dummy argument. [INTENSITY]
CylinderModel = CYLNDR(Intensity,Radius,Depth_Bottom,Incl,Decl,R,Theta,Depth_Top)
------------------------^
I'm sure its a simple thing but I've been reading and banging my head on this for 2 days.
HOW do I declare a function so that it can be called from elsewhere in the same file??
thanks
Marc Pelletier
Goldak Airborne Surveys
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
removing the statement
REAL*8 Cylndr
the code shown compiles without error.
The variables I_P, D_P are unused in the Interface block.
VariablesCells and CellSize are unused variables in CylinderModel - all of which may be due to snipping out some code from the real world source ?
Les
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Les Neilson
removing the statement
REAL*8 Cylndr
the code shown compiles without error.
The variables I_P, D_P are unused in the Interface block.
VariablesCells and CellSize are unused variables in CylinderModel - all of which may be due to snipping out some code from the real world source ?
Les
Thanks Les,
I guess I was kind of sloppy n my cut and paste, and not at all clear on the interface issue. The original code just exposed the function as a variable, as in the code included above. I started from scratch and rebuilt the dll using interface sections for each function. With a bunch of other mods I got it to compile. But I have a couple of questions:
Is there any way to declare a function so that it is visible to a bunch of other functions without having to build interface sections constantly? Is that what modules are for? I guess I would like to find a document that describes all of the scoping rules and options? The help file seems kind of circular on these topics.
cheers,
Marc Pelletier
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, this is what modules are for. There are any number of good texts on the Fortran language that cover issues such as scoping, or you could try reading the Fortran 2003 standard (which can be obtuse in many places.)
For a DLL, a reasonable implementation is one or modules which contain module procedures, each with a DLLEXPORT attribute directive. When the DLL is built, the compiler will also create compiled module (.mod) files. You will need to make these visible to the user of the DLL - add them to the INCLUDE path. The DLLEXPORTs will turn into DLLIMPORTs on USE, which is handy.
For a DLL, a reasonable implementation is one or modules which contain module procedures, each with a DLLEXPORT attribute directive. When the DLL is built, the compiler will also create compiled module (.mod) files. You will need to make these visible to the user of the DLL - add them to the INCLUDE path. The DLLEXPORTs will turn into DLLIMPORTs on USE, which is handy.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Since you're just returning to fortran, many changes! Time to brush up on all the changes!
I recommend getting a book or two on Fortran90, 2003, etc.
here's a resource with listings of books, etc:
http://www.fortran.com/metcalf.htm
Of those, I'd recommend:
Fortran 90 Programming - Ellis, Philips, Lahey, Addison Wesley, Wokingham, 1994, ISBN 0-201-54446-6.
or a more recent book on 2003 by one or more of the authors or Metcalf.
Brian

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page