Call a c++ subroutine from fortran 4.1

I would like to pass one byte of data to a c++ subroutine and am having a problem understanding how. I don’t follow the Interface command usage.

Welcome to the forum. Your question is a trifle unclear, but the mention of “fortran 4.1” seems to hint at a very old compiler. Could you be more specific? If you are indeed using the old compiler I am thinking about, then it is high time that you upgrade, if at all possible. With the publication of the Fortran 2003 standard, the interfacing between Fortran and C has become standardised. The interfacing with C++ as always has to be via a C-compatible interface, but that is something on the side of C++.

What we need to know is at the very least the calling sequence of this C++ routine and what compiler you are using: not just the version number, but also the brand.

I have been using the Microsoft Fortran 4.1 for 35 years now and see no reason to change. It is far easier to use than today’s massively bloated compilers. I don’t program in c++; someone else has the subroutine and I want to call it with a single argument (or address(argument) as Fortran does unless the Interface command is used, of which I don’t know how).

Well, that compiler has not been maintained in several decades and I have no idea what the interface method was. Up to the Fortran 2003 standard every compiler came with its own methods. I could probably reconstruct several of these, but not the one used by the MicroSoft FORTRAN compiler.
If the interface is indeed so simple, then you will probably have to define a C intermediate routine with a name in capitals and an argument that is an integer pointer. Something along the lines:

extern "C" {
void CALLIT( int *something ) {
    ... call the C++ routine
}
}

The trick is to determine the right naming convention for “CALLIT”. It could be this, but there could also be an underscore somewhere. Or the name should be “callit”. You will have to consult whatever documentation you have for solving this riddle. Or determine it by trial and error.
We can help sort out the details, but you will have to provide the information and do some testing.

Hmm… You brought me back to my Microsoft Fortran Powerstation days.

Some call it bloat, I call it “features” .

The problem is that back then, interoperability with C was not standard, so you had to:

  • Rely on whatever the compiler’s documentation provided.
  • Be aware of the calling convention (STDCALL or C).
  • Check if INTERFACE blocks were already supported or the INTERFACE TO extension had to be used instead.
  • Use specific compiler’s directives (that looked like comments but started with DEC$ or MS$) to decorate the interface’s arguments.

As you can see, it’s way too complicated to use a compiler that doesn’t support Fortran 2003’s bloat interoperability with C.

2 Likes

I don’t think you need a modern compiler. C is always call-by-value and Fortran usually uses call-by-value for scalars, so I would try defining a logical*1 or character*1 and passing that. I have done the reverse (calling C from Fortran), with only Fortran 77 level code, but only for arrays. The main problem is that since you can only do I/O from the language of the main program, it is impossible to get any help from debugging print statements. You could return some information with the return code. Start with some experiments with a 3 line C subroutinebefore you work on the real code. My experience was decades ago, but in this case that may make it more relevant.

Thank you. I am going to try your suggestion. I think that the INTERFACE TO statement can change the Fortran call argument from the address(data) to data itself in a local subroutine used for the C call. But I’m not clear how to fully use that statement.