Inteoperabilidade entre as linguagens C e Fortran
Autor: Claudemir | Publicado: 2014-08-01T17:26:00-07:00

É bastante buscado um programa que contenha um código tanto em Fortan quanto em C e na qual uma rotina escrita numa das linguagens seja capaz de chamar outra rotina escrita na outra linguagem. O compilador de Fortran da intel® tem suporte para o padronizado mecanismo do Fortran 2003 que parmite o código em Fortran se cominicar de forma confiável (ou interoperar) com um código em C. 
&nbsp;Como chamar um programa em C a partir de um em fortran e como chamar um programa fortran a partir de um em C, tema de hoje. 

Para chamar funções em c a partir de um programa Fortran ou chamar subrotinas em Fortran a partir de C envolve resolver as seguintes problemas:

* 'Case sensitivity' ( uma vez que C é 'case sensitive' porém fortran não é)
* Possivel sublinhado adicional ("_") em nomes de funções em C (o
&nbsp;&nbsp; sublinhado é adicinado por alguns compiladores em fortran.)
* Possiveis bibliotecas adicionais em Fortran que precisam ser linkadas para
&nbsp;&nbsp; construir executáveis.
* Subrotinas em fortran são sempre "chamadas por referência" enquanto
&nbsp;&nbsp; em C podem ser tanto "por referência quando por valor". 

No que se segue, especificos exemplos são dados para compiladores intel e compiladores GNU. Se vc está usando outro compilador mudanças podem ser requeridas.

C chamando subrotinas em fortran suboutines
Exemplo de programas em C. Programa principal (c-call-f.c) -- note o sublinhado arrastado
no nome da função for_sub_:
&nbsp;
#include 
void for_sub_(int *, double *, double *, int *);
int main()
{
int i = 1, ny = 3;
double pi = 3.14159;
double y[] = {1.1, 2.2, 3.3};
// pular uma linha para melhor visualizacao
printf("\n");
printf("_____________________________________________\n");
printf(" C chamando subrotina em fortran, passando\n");
printf(" i = %d, pi = %g\n", i, pi);
printf(" y[] = %g, %g, %g\n", y[0], y[1], y[2]);
printf("_____________________________________________");
//pular uma linha para melhor visualizacao
printf("\n");
for_sub_(&amp;i, &amp;pi, y, &amp;ny);
return 0;
}


Programa exemplo: subrotina em fortran, em "formato livre (free format)" ( f_sub.f) 

subroutine FOR_SUB(i, pi, y, ny)IMPLICIT NONEinteger :: i, nydouble precision :: pidouble precision :: y(ny)! pular uma linha para melhor visualizacao no terminalprint *, " "print *, "____________________________________________"print *, "Esta eh uma subrotina em Fortran..."print *, "i = ", i, ", pi = ", piprint *, "y = ", y(1:ny)print *, "____________________________________________"! pular uma linha para melhor visualizacao no terminalprint *, " "end subroutine FOR_SUB

Como compilar:

Usando compiladores Intel icc e ifort
$ icc -c c-call-f.c
$ ifort -free -c f_sub.f
$ icc -o c-call-f-icc  c-call-f.o  f_sub.o -L/u/local/
compilers/intel/fce/current/lib -lifcore -limf
$ ./c-call-f-icc


Usando compiladores GNU gcc e gfortran 
$ gcc -c c-call-f.c
$ gfortran -ffree-form -c f_sub.f
$ gcc -o c-call-f-gcc  c-call-f.o f_sub.o  -lgfortran
$ ./c-call-f-gcc&nbsp;


Fortran chamando funções em C 
Exemplo de programa: Programa principal em fortran,
em free format 
(f-call-c.f):



program f_call_c
IMPLICIT none 
integer :: i = 1, ierr
double precision :: pi = 3.14159 
print *, "______________________________" 
print *, "Fortran chamando C, passando"
print *, "i = ", i, "pi = ", pi
ierr = cfun(i, pi)
print *, "______________________________"
end program f_call_c

Programa exemplo: função em C(cfun_c) -- note que o sublinhado arrastado no nome da
função cfun:
&nbsp;
#include 
int cfun_(int *ip, double *xp)
{
int i = *ip;
double x = *xp;
printf("\n");
printf("______________________________"); 
printf("Esta eh uma funcao em C...\n");
printf("i = %d, x = %g\n", i, x);
printf("______________________________");
printf("\n"); 
return 0;
}

Como se compilar

Usando compiladores Intel icc and ifort
$ ifort -free -c f-call-c.f
$ icc -c cfun.c
$ ifort -o f-call-c-icc f-call-c.o cfun.o
$ ./f-call-c-icc





Usando compiladores GNU gcc and gfortran
$ gfortran -ffree-form -c f-call-c.f
$ gcc -c cfun.c
$ gfortran -o f-call-c-gcc f-call-c.o cfun.o
$ ./f-call-c-gcc

&nbsp;
&nbsp;
REFERÊNCIAS:
http://hpc.ucla.edu/hoffman2/software/c-fortran-interop.php&nbsp;
https://gcc.gnu.org/onlinedocs/gfortran/Fortran-Dialect-Options.html
https://software.intel.com/sites/products/documentation/hpc/composerxe/
en-us/2011Update/fortran/win/bldaps_for/common/bldaps_interopc.htm
http://stackoverflow.com/tags/fortran-iso-c-binding/info
http://www.pgroup.com/userforum/viewtopic.php?p=7398&amp;sid=2a05571
a922045c6c4ae26d65bbf9fba
&nbsp;