4

I have very limited knowledge of C++ and even less of fortran, I am currently trying to call a fortran subroutine from a c++ main. Following some examples I was able to come up with the following code to call the

subroutine fireballess(ear,ne,parames,ifl,photar,photer)

here is my C++ code:

#include <stdlib.h>
#include <stdio.h>
#include <iostream>

using namespace std;

extern "C" void fireballess_( double *fear, int fne,double* fparames, int fifl, double *fphotar, double *fphoter);

int main(int argc, char ** argv)
{
    int ne,ifl;
    double *ear;
    double *parames;

    double *photar;
    double *photer;


    parames = new double[9];

// parames=[4.3,0.23,0.5,0.5,1.5,1.,1000.,2.15,3.]
        parames[0]=4.3;
        parames[1]=0.23;
        parames[2]=0.5;
        parames[3]=0.5;
        parames[4]=1.5;
        parames[5]=1.;
        parames[6]=1000.;
        parames[7]=2.15;
        parames[8]=3.;

ne = 2;

    ear = new double[ne];
 ear[0] = 0.;
 ear[1] = 20.;
 ear[2] = 40.;
 ifl=2;

    photar = new double[ne];
    photer = new double[ne];

    // Call a Fortran subroutine
    //subroutine_sum_(&size,vec,&sum);
    fireballess_(&ear,ne,&parames,ifl,&photar,&photer);

    cout << "Calling a Fortran subroutine" << endl;
    cout << "===============================" << endl;

for (int i=0;i<=ne;i++){
    cout << "ear = " <<ear[i-1]<< " - "<<ear[i] << endl;
    cout << "photar = " << photar[i] << endl;
    cout << "photer = " << photer[i] << endl << endl;
}

    delete[] ear;
    delete[] parames;
    delete[] photar;
    delete[] photer;
}

however, when I try to compile I get the following error:

call_fortran.cpp: In function ‘int main(int, char**)’:
call_fortran.cpp:45:53: error: cannot convert ‘double**’ to ‘double*’ for argument ‘1’ to ‘void fireballess_(double*, int, double*, int, double*, double)’
     fireballess_(&ear,ne,&parames,ifl,&photar,photer);

which I do not understand, since the photer variable follows the very same path of the photar variable, that gives no errors instead. I hope someone with a better understanding of pointers than me can help me here. Thanks

5
  • If you want us to comment on whether the prototype corresponding to the Fortran subroutine is correct, please show declarations of that subroutine's arguments. Commented May 22, 2019 at 10:09
  • 1
    ear is already of type double *, so &ear is of type double **, which differs from your decleration double *fear Commented May 22, 2019 at 10:12
  • @francescalus I suppose this is what you are referring to: integer ne,ifl real*4 ear(0:ne),parames(10),photar(ne),photer(ne) Commented May 22, 2019 at 10:12
  • @BennyK thanks, eliminating the & worked with the compilation. Now I am getting a segmentation fault instead -.-" Commented May 22, 2019 at 10:16
  • I also want to add that "ne", "ifl", "ear", "parames" and so on are dangerously close to identifiers contained in namespace std, which is why using namespace std; should generally be avoided, because else things in std could shadow identifiers in your code or the other way around. Commented May 22, 2019 at 10:31

1 Answer 1

1

ear is of type double* so that &ear is of type double**, which is not ok for the fortran function prototype. Getting rid of the &s might solve the issue (&parames, &photar and &photer are also double**):

Change

fireballess_(&ear,ne,&parames,ifl,&photar,&photer);

to

fireballess_(ear,ne,parames,ifl,photar,photer);

The fortran function prototype seems to be void fireballess_(double*, int, double*, int, double*, double). If that is really so, then photer still has to be changed to photer[i] where (i is an array-index like 0, 1, 2...).

If you really want to understand what is going on, I suggest reading a good C++ Pointer Tutorial.

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

3 Comments

Thanks, as you and BennyK pointed out that was the problem. I couldn't understand it since the error seemed to point to only one of the variables involved. The code compiles correctly now, even if I get a segmentation fault at runtime -.-"
1. Run it with a debugger 2. see which line throws the segfault 3. find out which access in that line exactly throws the segfault 4. find out how it came to the invalid access. OR even better: Don't use raw pointers at all. (In your case, you could use std::vector<double> or std::array<double, n> instead).
the call to the subroutine is causing the segmentation fault apparently, I found it out trying to move it inside the for cycle: changing the code from: fireballess_(ear,ne,parames,ifl,photar,photer); to cout << "Calling a Fortran subroutine" << endl; for (int i=0;i<=ne;i++){ fireballess_(&ear[i],ne,parames,ifl,&photar[i],&photer[i]); cout << "ear = " <<ear[i-1]<< " - "<<ear[i] << endl; cout << "photar = " << photar[i] << endl; } returned a working code up to the fireballess call. I'll go back to testing later, thanks

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.