- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If I have f90 code that calls C routines, is there a way to pass the contents of a module to the C routines like it was a header file? I dont want to have to put every array in the argument list of the call to the C wrapper.
thanks,
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In addition to using external variable name as mentioned by Steve the method I often use is to construct a derived type containing the module data
module mod_foo
type someType
sequence
...
end typeSomeType
type someOtherType
sequence
...
end someOtherType
...
type typeFoo
sequence
real :: variable
type(someType):: aSomeType
type(someOtherType)::bOtherType
end type typeFoo
type(typeFoo) :: Foo! the one and only Foo
end module mod_foo
Your Fortran program
program YourProgram
use mod_foo
...
Foo.variable = 1234.56
...
call Csubroutine(Foo)
...
end program YourProgram
Programming Hint
If your program is a conversion of a legacy F77 program (from COMMON to modules) you may find it inconvienent to change all references of "variable" to "Foo.variable" (or "Foo%variable". The technique I use is to enable the Fortran Preprocessor and use a #define to make the conversions automatic. The #defines are then placed into an #include file (not in the module, and not in a Fortran .FI file)
The define macro names are case sensitive --- make use of that.
! mod_foo.def - defines for mod_foo.f90
#define VARIABLE Foo%variable
#define SOMETHING Foo%aSomeType%something
...
Then at the top of the .F90 source file insert
#include "mod_foo.def"
Only include once per source file, usualy at the top of the file.
Often the legacy F77 used all upper case variable names. Therefor, in your derived types you can use lowercase names and not have to worry about conflicting names. If you forget the #include file (and use implicit none) you will have undefined variables at compile time. If you have the #include file and forget the use file you will have undefined variables at compile time. Both cases are easily identifiable and correctable.
Using this technique the same source file can be compiled as was using COMMONs or as intended using MODULES.
! YourProgram
! your comments here
! if _MOD defined use modules else use COMMONS
#ifdef _MOD
#include 'mod_foo.inc'
#endif
program YourProgram
#ifdef _MOD
use mod_foo
#else
INCLUDE'FOO.FI'
#endif
...
! untouched statements Either Foo%variable or VARIABLE from COMMON
A = VARIABLE
...
end program YourProgram
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>> I should also mention that if you share ALLOCATABLE or POINTER arrays in this manner, what you'll be sharing is the array descriptor and not the actual data. The layout of the descriptor is documented.
That is correct. Most C/C++ functions (easy way to write) expect the location of the first cell and a count of cells (or count of rows and cols) and do not go to the effort of deciphering the array descriptors (which is subject to change). Prototype:
void Csub(real* r, int n);
Therefore the fortran call would be
call Csub(%LOC(A(1)), size(A))
And consider:
#define CSUB(A) Csub(%LOC(A(1)), size(A))
then in your code you can use
CALL CSUB(SomeArray)
Note, I will leave it as a exercize to construct the CSUB macro such that the array can have dimension range starting at other than 1 and/or of different rank.
The #defines make it relatively easy to maintain identical source code statements while converting legacy code to the "modern" age of modules and cross language applications.
Might Intel consider adding an ATTRIBUTE for use in interface to specify if the address of the descriptor is to be passed or if the address of the first data cell is to be passed. This way there would be no ambiguity as to what is required to be passed
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

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