Calling Fortran code from C++ on Visual Studio 2015

Here I describe a little on how to call Fortran code from C++ using Visual Studio. I will be focusing on MinGW gfortran as that is a popular free Fortran compiler on Windows platform.

System Requirements:

  • Visual Studio 2015 (C++) (I am using the free community version)
  • MinGW gfortran (64bit, using the one from Msys here)

My Fortran code is just a simple function in a module:

module testfor
    use, intrinsic :: iso_c_binding
    implicit none
contains
    subroutine testingfor(x) bind(c, name="testingfor")
        implicit none
        double precision, intent(in) :: x

        print *, "# calling testfor in Fortran!!"
        print *, "x = ", x 
    end subroutine
end module testfor

Note that I am using Fortran 2003 standard “iso_c_binding”. The “bind” syntax allow you to customize the function name to be called in C++. Here I use the same name “testingfor”. If you are using the old (pre-2003) style, the naming convention for a function in a module may be a little complicated. Anyway, that helps us clean up the code a little.

Next, my C++ main function is very simple as well:

extern "C" {
	void testingfor(double* x);
}

int main(int argc, char* argv[]) {
	double y = 1.0;

	testingfor(&y);
}

The “extern C” syntax acts as an interface. Note that the input argument for the Fortran function must be a pointer as Fortran is pass-by-reference only.

Here is the main dish! In Windows, we need the “import” library (.lib) and dynamic library (.dll). To get these files, we need to the following steps:

gfortran -c testfor.f90

dllwrap.exe --export-all-symbols testfor.o -lgfortran --output-def testfor.def -o testfor.dll

lib.exe /machine:x64 /def:testfor.def

First command is simply compiling our Fortran module into an object file. Second command creates the definition file (.def) and the dll file (.dll). The dllwrap.exe comes with MinGW as for as I know. It may complain with the following error:

dllwrap.exe: no export definition file provided.
Creating one, but that may not be what you want

But I think we can ignore it.. The last line with lib.exe earlier is to create the import lib with the def file. Now we have what we need, the testfor.lib and testfor.dll.

Now we need to go into Visual Studio to set up. I don’t go over Visual Studio here. What we need to do is simply add the testfor.lib in the resource folder and let VS know you need it to compile. The last step can be done by adding “testfor.lib” into Project-> Properties-> Configuration Properties-> Linker-> Input-> Additional Dependencies. Remember the resultant exe file do require the testfor.dll in the path in order to run. Here is the result:

Hopefully this is useful.

Reference: http://www.cs.cmu.edu/~barbic/arpack.html