1

I have a bunch of fortran code that I am adapting with some c++ code. The problem area essentially boils down to this:

The C++ function that calls the fortran function:

extern "C" 
{
void CALX(float* w, int* nw, double* dw, int* idmx, int* lo);
}
void calcPort(float* w, int* nw, double* dw, int *idmx)
{
    int lo[250]; //>100 used for internal stuff
    //stuff
    CALX(w, nw, dw, idmx, lo);
    for(int i=0; i<100; ++i)
    {
        cout<<lo[i]<<", ";
        if(i%50 == 49)
        {
            cout<<endl;
        }
    }
    //more stuff
}

The important parts of the fortran function:

      SUBROUTINE CALX(W,NW,DW,LO) bind(C, name="CALX")                  CALX-001
        use iso_c_binding
C Lots o' comments
      LOGICAL LO(250)                                                   CALX-160
      DOUBLE PRECISION DW(1)                                            CALX-161
C Bunch o' common blocks
    1 READ (5,1000) TITLE                                               CALX-175
C some miscellaneous stuff dealing with a couple special title strings
      DO 4 I=1,100                                                      CALX-184
    4 LO(I)=.FALSE.                                                     CALX-185
      READ (5,1001) (LO(I),I=1,50)                                      CALX-186
      WRITE (6,*) SIZEOF(LO(1))
      WRITE (6,1001) (LO(I),I=1,50)
C IF LO(36)=.TRUE. RETURN TO RESTART A SEARCH SAVED ON TAPE 8           CALX-187
      IF (LO(36)) RETURN                                                CALX-188
      READ (5,1001) (LO(I),I=51,100)                                    CALX-189
      WRITE (6,1001) (LO(I),I=51,100)
C More stuff

To my eye this should work. After the function is called the c++ code should read 0 or non zero in the same pattern that the fortran does. Instead what I get is this:

This bit from the fortran write statements (which matches the input I redirect into it):

FFFFFFTTFFTTFFFTFFFFFFFFFFFTFFTTFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFTTTFTTTFFFFFFFFFFFFFFFFFTTFFFFFFFF

This bit from my loop.

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

Clearly there is some failure to communicate. Why? How do I fix it?

6
  • Shouldn't you have a declaration of W and NW on the Fortran side.?Is a LOGICAL really represented the same way as an int? Commented Feb 11, 2014 at 19:55
  • Yeah it is, FORTRAN LOGICALs are equivalent to int, LOGICAL*1 is equivalent to bool. and W and NW are handled via the implicit declaration insanity of FORTRAN. Commented Feb 11, 2014 at 19:57
  • Ah, and they're pointers because everything is by reference. Sorry, my Fortran experience is mumble years ago. Commented Feb 11, 2014 at 20:03
  • 1
    The Fortran ISO C Binding provides logical type C_BOOL to match C type _Bool. So you don't have to guess equivalents. Commented Feb 11, 2014 at 20:08
  • 3
    You could write a Fortran "glue routine" that receives C-binding arguments, assigns them to variables of conventional Fortran types, and calls the unmodified existing routine with those types and reverses for any output arguments. That would allow you to fully use C/Fortran interop without modifying existing Fortran code. Commented Feb 11, 2014 at 21:06

1 Answer 1

2

You have five arguments in the C++ call. Your Fortran code takes four.

(Note that USE ISO_C_BINDING doesn't, on its own, changethe behaviour of code. BIND(C) does, though.)

Sign up to request clarification or add additional context in comments.

2 Comments

I noticed that shortly before someone came into my office to talk to me, giving time for this answer to happen. Thanks for spotting that. After fixing it everything works and I can understand why it was not working before (since it was reading the values into a non-existant integer array, explains why I was getting bugs on exit, something important was getting overwritten). Anyways why wasn't the disparity between the prototype and the actual code noticed by the compiler?
Goes to show, one should be careful when reading the declarations of functions with almost the same name. (CALZ vs CALX) Also, thanks for the hint about the ISO_C_BINDING

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.