Calling FORTRAN from C

Robert Boehne rboehne@ricardo-us.com
Mon Dec 4 07:14:00 GMT 2000


To call FORTRAN from C, you should declare the subroutines
you want to call as extern "C" with their names in uppercase
and underscores prepended to them.  For example to call
the fortran function INTEGER NINT( INTEGER ) from C you would
declare it as:

extern "C" {
int _NINT( int &arg1 );
}

A FORTRAN subroutine is just a function returning void, so it would
be extern "C" { void _SUB1(sometype &arg1, etc...); }

You can also find more details about this in the Fortran FAQ.
In general though, you should use "nm" on your object files
to determine the exact names the fortran compiler is giving
the functions you create.  It should be easy to do this with
gcc/g77, some compilers make it more difficult, i.e. HP has to have
a fortran initialization routine called before intrinsic functions
such as "GETARG" can be used, so YMMV.

Cheers!

Robert Boehne

Robert Kuhn wrote:
> 
> To:gcc@gcc.gnu.org
> From: Bob Kuhn
> Subject: Calling FORTRAN from C
> 
> I have a FORTRAN program in which I do not know in advance how large
> some of the arrays will be.   Standard FORTRAN has no "alloc"
> statement to allocate arrays at execution time.
> 
> Looking at the GNU FORTRAN documentation, I have concluded that
> there is no direct way to do this.  AM I CORRECT?
> 
> In ABSOFT PC FORTRAN and C, I was able to solve the problem by
> allocating the arrays in C and calling my FORTRAN program as a
> subroutine from C.  Is this practical to do in GNU FORTRAN and C?  I
> do not want to spend a lot of time if this is very difficult to
> accomplish.
> 
> In order do this, I need to do the following:
> 
> 1. How to call FORTRAN from C.
> 2. I need to able to pass integers, arrays (both numeric and
>    character) to the FORTRAN program.
> 3. I need to be able to use "alloc" in C with adjustable arrays in
>    FORTRAN.
> 
> I was able to do all these things with the ABSOFT PC compilers.  I
> have no idea how difficult this is to do with the GNU compilers.
> 
> Appendix's 1 and 2 contains two programs that worked on the ABSOFT
> PC compiler. Appendix 1 contains the simplist possible program with
> C calling FORTRAN. I tried it on the GNU UNIX compiler on they did
> not work.  Details are in that appendix.  Appendix 2 contains very
> simple working PC programs with all the features that I need.
> 
> I have two questions:
> 1. Why did the programs in appendix 1 not work?
> 2. Will it be difficult to the programs in appendix 2 to work with
>    the GNU compilers?  Do you consider this a practical approach?
> 
> Any advice on this subject will be greatly appreciated.
> 
> Sincerely,
> Bob Kuhn
> 
> P.S. When I ran the ABSOFT version I did not use "#include <g2c.h>"
> ----------------------------------------------------------
>       Appendix 1 -- Simple Program for calling FORTRAN from C
> 
> 1. C Program  (testbob.c)
> 
>    #include <stdio.h>
>    #include <stdlib.h>
>    #include <string.h>
>    #include <g2c.h>
> 
>    int main(int argc, char * argv[])
>    {
>    void sub1(void);
>    printf("Start Program\n");
>    sub1();
>    printf("End Program\n");
>    exit(0); return(0);
>    }
> 
> 2. FORTRAN SUBROUTINE (sub1.for)
> 
>       subroutine sub1
>       print *, 'This is SUB1'
>       return
>       end
> 
> 3. Compile steps
>    gcc -c testbob.c
>    g77 -c sub1.for
> 
> 4. Link edit step
>    g77 testbob.o sub1.o -o testbob
> 
> 5. Link edit error message:
> 
>    /data/user/rmk/mars$ g77 testbob.o sub1.o -o testbob
>    Undefined
>    Undifined                        first referenced
>     symbol                             in file
>    sub1                                testbob.o
>    ld: fatal: Symbol referencing errors. No output written to
>    testbob collect2: ld returned 1 exit status
> 
> The question is: WHAT DID I DO WRONG?
> 
> ----------------------------------------------------------
>        Appendix 2 -- Simple Example with Dynamic Allocation
> 
> 1. C Program
> 
>    #include <stdio.h>
>    #include <stdlib.h>
>    #include <string.h>
>    /*#include <g2c.h>*/
> 
>    #define false 0
>    #define true 1
> 
>    int main(int argc, char * argv[])
>    {
>    /* Use the typedefs in <g2c.h> */
>    /* real *x; integer n; */
>    float *x; long n; short j;
>    char c[12] ="All is well";
> 
>    void test5a(long *n,float *x,char *c);
> 
>    printf("Start Program\n");
>    if ( (x = calloc(1000,4)) == NULL)  {
>       printf("Allocation of 'x' failed\n");
>       exit(1);
>       }
>    n=1000;
>    printf("n=%ld\n",n);
> 
>    for (j=0; j < 1000; j++) {x[j]=2*(j+1);}
> 
>    printf("Call subroutine\n");
>    test5a(&n,x,c);
> 
>    printf("End Program\n");
>    exit(0); return(0);
>    }
> 
> 2. FORTRAN SUBROUTINE
> 
>       subroutine test5a(n,x,c)
>       dimension x(n)
>       character*12 c
>       print *,'n=',n,' x(501)=',x(501),' c=',c(1:11)
>       return
>       end
> 
> This program worked with the ABSOFT PC compiler.  How difficult
> would it be to get this program to work with the GNU system?

-- 
Robert Boehne             Software Engineer
Ricardo Software   Chicago Technical Center
TEL: (630)789-0003 x. 238
FAX: (630)789-0127
email:  rboehne@ricardo-us.com


More information about the Gcc mailing list