I feel like this should be an easy question, but I can’t get it to work. I have some Fortran code that takes an input like:
SUBROUTINE TRACE(X,Y,NAME,XX,YY)
EXTERNAL NAME
CALL NAME(X,Y,XX,YY)
and I’m trying to pass in a name from C++ in the form:
float x,y,xx,yy;
char * name="IGRF";
trace_(&x,&y,name,&xx,&yy);
It compiles, but I always get segfaults when I try to call the NAME subroutine. A subroutine called IGRF is defined in the file, and I can call the IGRF subroutine directly from C++, but need this TRACE routine. When running in gdb, it says the NAME variable comes through as a pointer to void.
I’ve tried passing NAME, &NAME, &NAME[0], a char NAME[4] that’s stripped of its \0 to perfectly fit the name, and they all come back showing the same void pointer. Does anybody know how to get a function name from C++ into that EXTERNAL variable in Fortran?
Thank you
So one advantage of Fortran2003 and later is that C interoperability is defined into the standard; it’s a bit of a PITA to use, but once it’s done, it’s guaranteed to work across platforms and compilers.
So here’s
cprogram.c, calling a Fortran routinegetstring:and here’s
fortranroutine.f90:The makefile is simple enough:
and running it works, under both gcc/gfortran and icc/ifort:
Update: Oh, I just realized that what you’re doing is rather more elaborate than just passing a string; you’re essentially trying to pass a function pointer pointing to a C callback routine. That’s a little tricker, because you have to use Fortran
interfaces to declare the C routine — just using extern won’t work (and isn’t as good as explicit interfaces anyway, as there’s no type checking, etc.) So this should work:cprogram.c:
froutine.f90:
And the results: