c - How to properly link gfortran and gcc? -


i trying write c function calls piece of fortran code. thought easier try link fortran code directly versus trying rewrite fortran c. using gcc/g++/gfortran on mac directly downloaded binaries , installed them.

the fortran code @ https://www.ngdc.noaa.gov/iaga/vmod/igrf12.f. specific subroutine want call subroutine igrf12syn (isv,date,itype,alt,colat,elong,x,y,z,f)

the wrapper wrote follows:

 #include <stdio.h>   extern void igrf12syn( int *isv, double *year, double *itype, double *alt,  double *colat, double *elong, double* x,double* y, double* z, double* f );  int main(){     double b[4], babsdervs[3], brdervs[3], bthdervs[3], bphdervs[3];     double r, th, ph,year,alt2,lat,colat,elong,x,y,z,f;     int isv;      // igrf12syn (isv,date,itype,alt,colat,elong,x,y,z,f)     r = 6371e3;     th = 0.57;     ph = 0;      year = 2015;     alt2 = 200.0;     lat = 33.25;     colat = 90.0-lat;     elong = 0.0;     isv =1;     igrf12syn_(&isv,&year,&isv,&r, &th, &ph,x,y,z,f);      printf("%0.4e",f);  return 0;  } 

the commands using compile , call are:

/usr/local/bin/gcc -lgfortran -c testigrf.c igrf12.f /usr/local/bin/gcc -lgfortran -o b.out testigrf.o igrf12.o  

the error is:

duplicate symbol _main in: testigrf.o igrf12.o ld: 1 duplicate symbol architecture x86_64 collect2: error: ld returned 1 exit status make: *** [igrf] error 1 

i understand error means , can produce nm files .o files shows both of main functions. however, not sure how change fortran code rid of error.

so questions following: 1. how change fortran or c code fix issue? particularly, since fortran code starts program igrf

  1. am calling igrf12syn routine properly? worried not calling correctly. may doing poor job passing in variables, has done reference.

thanks help, , please let me know if doing silly in calling routines.

firstly, c program testigrf.c defective. is, have warning:

testigrf.c: in function ‘main’: testigrf.c:23:5: warning: implicit declaration of function ‘igrf12syn_’ [-wimplicit-function-declaration]      igrf12syn_(&isv,&year,&isv,&r, &th, &ph,x,y,z,f);      ^ 

which occurs because have declared function called igrf12syn , invoked 1 called igrf12syn_, compiler knows nothing.

change igrf12syn_ igrf12syn, recompile, , errors revealed are:

testigrf.c: in function ‘main’: testigrf.c:23:26: warning: passing argument 3 of ‘igrf12syn’ incompatible pointer type [-wincompatible-pointer-types]      igrf12syn(&isv,&year,&isv,&r, &th, &ph,x,y,z,f);                           ^ testigrf.c:3:14: note: expected ‘double *’ argument of type ‘int *’   extern void igrf12syn( int *isv, double *year, double *itype, double *alt,               ^ testigrf.c:23:44: error: incompatible type argument 7 of ‘igrf12syn’      igrf12syn(&isv,&year,&isv,&r, &th, &ph,x,y,z,f);                                             ^ testigrf.c:3:14: note: expected ‘double *’ argument of type ‘double’   extern void igrf12syn( int *isv, double *year, double *itype, double *alt,               ^ testigrf.c:23:46: error: incompatible type argument 8 of ‘igrf12syn’      igrf12syn(&isv,&year,&isv,&r, &th, &ph,x,y,z,f);                                               ^ testigrf.c:3:14: note: expected ‘double *’ argument of type ‘double’   extern void igrf12syn( int *isv, double *year, double *itype, double *alt,               ^ testigrf.c:23:48: error: incompatible type argument 9 of ‘igrf12syn’      igrf12syn(&isv,&year,&isv,&r, &th, &ph,x,y,z,f);                                                 ^ testigrf.c:3:14: note: expected ‘double *’ argument of type ‘double’   extern void igrf12syn( int *isv, double *year, double *itype, double *alt,               ^ testigrf.c:23:50: error: incompatible type argument 10 of ‘igrf12syn’      igrf12syn(&isv,&year,&isv,&r, &th, &ph,x,y,z,f);                                                   ^ testigrf.c:3:14: note: expected ‘double *’ argument of type ‘double’   extern void igrf12syn( int *isv, double *year, double *itype, double *alt,               ^ 

read diagnostics , fix errors before go further. might fixed, example, changing:

double r, th, ph,year,alt2,lat,colat,elong,x,y,z,f; 

to

double r, th, ph,year,alt2,lat,colat,elong,x,y,z,f,itype; 

and changing:

igrf12syn(&isv,&year,&isv,&r, &th, &ph,x,y,z,f); 

to:

igrf12syn(&isv,&year,&itype,&r, &th, &ph,&x,&y,&z,&f); 

that satisfy compiler, though may not express intentions, not clear me.

you understand cannot link 2 programs single program, since linker find duplicate main functions. need link c main program fortran subroutine igrf12syn.

next, download , save file https://www.ngdc.noaa.gov/iaga/vmod/igrf12.f. open in text/programming editor. select of lines - complete lines, including leading space - compose subroutine igrf12syn, from:

  subroutine igrf12syn (isv,date,itype,alt,colat,elong,x,y,z,f) 

to:

 end 

save selection copied in new file igrf12syn.f in same directory testigrf.c.

then, open console in directory , execute following commands:

$ gcc -c -o testigrf.o testigrf.c $ gfortran -fno-underscoring -c -o igrf12syn.o igrf12syn.f $ gfortran -o testigrf testigrf.o igrf12syn.o 

these compile , link program testigrf in same directory.

finally, repeat first 2 commands, each additional option -wall, see warnings not yet aware of. consider fixing program remove warnings, may mean program not behave expect. include -wall in gcc/g++/gfortran compiler options when compiling code of importance you.


Comments

Popular posts from this blog

routing - AngularJS State management ->load multiple states in one page -

python - GRASS parser() error -

Swift game error message -