Friday, August 24, 2012

Fortran, C++ and qmake

Qt Creator Logo
   Call me a noob, but I love using Qt Creator even when I'm not programming a GUI. The UI greatly facilitates code writing: the syntax highlighting is very customizable, it shows you the methods of a class when you use the . or -> operators, it makes the build process faster and easier to configure (sometimes), etc.

   Now, I didn't want to make this a post about Qt Creator, so here comes the meat. I've been trying to add Fortran code to my numerical library, something I think is pretty common in scientific circles. Of course, that's been done before, but my research has yielded one link for Fortran and Qt. 

   I'm using D.E. Amos' Fortran code to compute Bessel and Hankel functions of complex arguments and all (real) orders (we use identities to convert the negative order computations to positive order ones). Complex orders are not supported. Work by Temme could be used for this, but maybe a later time. 

   I have two Fortran source files that must be incorporated into a C++ numerical library. Using qmake, this is child's play. 

  • First, add the Fortran source files as sources in your .pro file. 
  • SOURCES += machine.for zbesh.for

    Those are the names of the Fortran sources files used by Amos.  
  • Second, create a C++ header file that links to the Fortran subroutines inside the source files. 

    A couple things about this linkage. Notice that I appended a _ to the Fortran subroutine names. The extern keyword tells the compiler that a separately compiled object will be used. By default, g++ will append _ to Fortran subroutines when creating an object file. This means that if you change this compiler setting, be sure to remember to change your function declarations in your C++ header file.
    Also, the functions take pointers to variables. In Fortran, all functions take their arguments by reference. It is thus necessary to use pointers when using Fortran subroutines in C++. 
  • You're done! You can now use your Fortran subroutines in your C++ program! Just don't forget to add the
    -lgfortran
    when compiling either the program you are writing or a program that uses a library that uses Fortran subroutines.

Wow, that last sentence was terrible.

   Anyway, have fun programming!