views:

406

answers:

5

Hi every one, i am looking for a way, how i can integrate a c++ code with fortran code (i want simply call some C/C++ functions in the fortran code).

I have found some proposals for gcc or console compilers, but i have not any idea how to translate this approach to solve integrationproblem within the visual studio.

At the time I am thinking about creating a dll form c++ code and calling it from Fortran code.

Has someone already seen a solution? Or what is about overhead for calling function from dll? My fortran code transfers a lot of memory into C function, is there any problems, if i would solve this problem with dll?

thx.

PS I am using Visual Studio 2008 Prof and Intel compilers 10

PPS I think, i have to specify more concrete, what i want: i want to compile a fortran project in visual studio, which uses some C functions.

+1  A: 

I integrated C and Fortran about 20 years ago and maintained this integration up to 5 years ago. The tricks I used were:

  • I noticed that the Fortran compiler puts all symbols in uppercase, so make sure your C/C++ functions are written in uppercase as well. To verify how symbols are put in the .OBJ file, use DUMPBIN.
  • The Fortran compiler does not understand the name-mangling done by the C++ compiler. Compile all your C++ functions using the C style convention (using extern "C")
  • Arguments in Fortran are always put on the stack using references/pointers. Therefore, use pointer-arguments in your C function.

To be honest, I gave up integrating C and Fortran when I switched to VS2005, so things might have changed since then. Nevertheless, it's still a good idea to use DUMPBIN to see what kind of symbols the Fortran compiler produces, and adjust the compilation of C/C++ sources to fit with that.

Patrick
They have changed a bit (in particular mixed-language projects are no longer supported), but this is all good advise. The only thing I'd change is to suggest not to rely on the defaults but to use INTERFACE blocks to specify everything exactly. Expanded on in an answer.
T.E.D.
A: 

This is the how it works with gcc and console

c.c:

#include <stdio.h>

void f_()
{
    printf("Hi from C\n");
} 

fortran.f90

PROGRAM HelloWorld
   CALL f
END PROGRAM HelloWorld

Makefile

SRCDIR=.

all: clean release run

release:
    gcc -c c.c -o c.out 
    gfortran -c fortran.f90 -o fortran.out
    gfortran -o out.exe fortran.out c.out
run:
    out.exe

clean:
    @$(ZSHMAGIC)  rm -rf *.exe core* *.o a.out 2> /dev/null

One other question: have i always add '_' after c-function name, which i use in the fortran program?

LonliLokli
Use DUMPBIN to see how the Fortran compiler generates the symbols. Then adjust the names of your C functions to fit with that.
Patrick
I would like to do it possible platform independent. Under linux i use nm, therefore i know, that i have to add under-space.
LonliLokli
+1  A: 

We do it where I work.

Assuming you are using the Intel Fortran compiler, look up its docs. By default Intel Fortran passes everything by reference and (I believe) uses the C calling convention, with an all caps identifier. Strings are a particular issue, as Fortran likes to pass the length as a hidden parameter, with a compiler setting for where it goes in the parameter list.

A wise programer doesn't rely on defaults (where a mistake can lead to undefined behavior), and will use the intel INTERFACE statements to specify calling convention, parameter passing, and the link name for the routine. The information on this page (ATTRIBUTES Properties and Calling Conventions) is a must-read. In particular you need it to understand the arcane rules for when and where string length parameters will be passed. I have a printout of it that I keep on my person. :-)

One other thing to note is that versions of VisualStudio past 6 don't like mixed Fortran and C projects. We solved the problem by creating custom project files calling out to makefile, but that's a PITA. I'd suggest going with the flow and using separate projects unless you are doing this a lot like we are.

T.E.D.
What is the workflow, if i will use 2 projects?
LonliLokli
Well, presumably you'd have one containing your main pogram entry point (eg: `main()` if it is C) and all the rest of the code in its language, and the other would contain all the code for the other language and be compiled to a .lib file. Both in the same "solution", of course.
T.E.D.
+3  A: 

There is a new way to do this that has many advantages -- use the Fortran 2003 ISO C Binding. This is a standard and therefore largely OS and language independent way of interfacing Fortran and C (and any language that will use C calling conventions). Intel Fortran 11 supports along with numerous other compilers -- not sure about version 10. Using the ISO C Binding, you can match any C name (any case), don't have to worry about underscores (and variations between compilers) and can specify the types and calling methods (by reference, by value) for the arguments. Intel provides some examples in a folder with their compiler; there are also examples in the gfortran manual and a discussion of additional considerations for Windows. There are previous questions & answers here and on the Intel Fortran forum.

M. S. B.
My problem now is to integrate my c++ into existing Fortran project in the Visual Studio 2008. Is there a tutorial how to do it?
LonliLokli
@LonliLokli - I don't have VS on the machine I'm writing this from, but isn't there something about mixed language programming in fortran's help. I'm sure I saw it at some time.
ldigas
Apart from that, what MSB said.
ldigas
There are some tips about Intel Fortran and Visual Studio at http://software.intel.com/en-us/articles/configuring-visual-studio-for-mixed-language-applications/
M. S. B.
+1: Far better to use recent (and useful) features of the language, than the old lash-ups some other respondents have suggested.
High Performance Mark
Cool! Too bad the 9.1 I'm using doesn't have it. I have to use non-standard `Interface` statements left over from when DEC owned the compiler instead.
T.E.D.
@T.E.D: you ought to move :-) If you can't move your compiler to 11.1 then move yourself to a shop with the $$$ for annual maintenance.
High Performance Mark
We will be upgrading by the end of the year, if I understand correctly. The issue is that we have a large amount of interconnected tools in our toolchain that all have to work together (including RTX - a sort of custom HAL layer to Windows, and some we maintain ourselves in our limited "overhead" time). It is always a few years after a new release of Windows until every tool in the chain gets updated and they can all be upgraded together.
T.E.D.
A: 

Solution found: solution link

i have had several problem with linking, which could be solved with adding in project properties.

code for testing:

#include <stdio.h>

extern "C"
{
    void f() 
    {
        printf("hi from c\n mega test");
    }
}

fortran code

PROGRAM HelloWorld
use, intrinsic :: iso_c_binding
implicit none 
interface
    subroutine f( ) bind( c )
        use, intrinsic :: iso_c_binding
    end subroutine f   
end interface  
call f
END PROGRAM HelloWorld

on demand i can upload the testproject. thanks all, hopefully it was my last problem with c and fortran

LonliLokli
I have had a problem with linking, when i was using uppercase in the functionsname.
LonliLokli