problem to link c++ and fortran

Hello everyone,

I am trying to use a Fortran library in my C++ code. I have already succeeded in calling a routine of this library in my program. But now, the routine I want to use, is a minimization algorithm. So I need to pass a C++ function as an argument. When I try to use the routine, I can compile but when I want to build my program it doesn't work any more, and told me I have a "segmentation fault". So obviously, I write out of memory but I can't understand where or why.

So if any one knows something about this type of issue, it would be very nice to explain me why I am wrong.

Right now, I wonder if calling dynamic arrays in a Fortran subroutine is correct, or if I have to call static arrays. Does any one knows something about it?

Best

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#pragma once

#include "Layer.h"
#include "MilieuDiffusant.h"
#include "MilieuDiffusantPassif.h"
#include "ModePassif.h"
#include <iostream>
#include <fstream>

using namespace std;

// Fortran declaration of routine, e04ccf is the one which doesn't work, the second one is the one I want to minimize, the third is usually used to show the evolution of the minimization in real time 
extern "C"
{
        void e04ccf_(int*, double**, double*, double*, int*, double(*)[2], double(*)[2], double(*)[2], double(*)[2], double(*)[3] , double(*)[2][3], void(*) (int*, double**, double*), void(*) (double*, double*, double***, int*, int*, int*), int*, int*);
        void funct_(int*, double**, double*);
        void monit_(double* fmin, double* fmax, double*** sim, int* n, int* nvert, int* ncall);
}
MilieuDiffusantPassif MDP(1.0,1.05,200*1e-9,100*1e-9, 161, 0.9);

int  main()
{
//the parameter I use to evaluate the function e04ccf
        int n = 2, ifail, iw = n+1, maxcal = 100;
        double w1[2]={0.0,0.0}, w2[2]={0.0,0.0}, w3[2]={0.0,0.0}, w4[2]={0.0,0.0}, w5[3]={0.0,0.0,0.0}, w6[2][3]={{0.0,0.0,0.0},{0.0,0.0,0.0}};
        double temp[2] = {10.5*1e6,-0.6*1e6};
        double  tol = 1e-12;
        double* x = temp;
        double f = MDP.ModuleM22(*x,*(x+1));


        e04ccf_(&n, &x, &f, &tol, &iw, &w1, &w2, &w3, &w4, &w5, NULL, &funct_, &monit_, &maxcal, &ifail);
  
        return 0;
}
// C++ function I have to use in the Fortran routine
static void funct_(int* n, double** xc, double* fc){*fc = MDP.ModuleM22(**(xc),*(*xc+1));};
static void monit_(double* fmin, double* fmax, double*** sim, int* n, int* nvert, int* ncall){};


What compiler/environment are you using?
Are you aware that you cannot cast w6[2][3] to double **
Now that you mention it, I'm not sure what x is supposed to represent but I'd bet it's wrong.

Are you aware the Fortran and C index multidimensional arrays differently?

You might want to take a look at these.
http://www.cae.tntech.edu/help/programming/mixed_languages
http://www.math.utah.edu/software/c-with-fortran.html
Thank you all for your answers. Finally, I have found my mistake. It was indeed a problem with the arrays (like you says coder777). In fact, arrays in c must be declared as dynamic ones, even if they are called as static in Fortran language. I give you the solution.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

#pragma once

#include "Layer.h"
#include "MilieuDiffusant.h"
#include "MilieuDiffusantPassif.h"
#include "MilieuDiffusantActif.h"
#include "Mode.h"
#include "ModePassif.h"
#include "ModeActif.h"
#include <iostream>
#include <fstream>

using namespace std;

//Définition des routines Fortran
extern "C"
{
        void e04ccf_(int*, double*, double*, double*, int*, double(*), double(*), double(*), double(*), double(*) , double(*)[3], void(*) (int*, double*, double*), void(*) (double*, double*, double***, int*, int*, int*), int*, int*);
        void funct_(int *n, double* x, double *f);
        void monit_(double* fmin, double* fmax, double*** sim, int* n, int* nvert, int* ncall);
}

// Définition du milieu diffusant
MilieuDiffusantPassif MDP;


// Définition des fonctions C++
static void funct_(int *n, double* xc, double *fc){*fc = MDP.ModuleM22(xc[0],xc[1]);};
static void monit_(double* fmin, double* fmax, double*** sim, int* n, int* nvert, int* ncall){};

int  main()
{
        MDP.Charger("Milieu1D");
        int n = 2, ifail = 0, iw = n+1, maxcal = 1000;
        double w1[2], w2[2], w3[2], w4[2], w5[3],w6[2][3];
        double x[2] = {8.5*1e6,-0.2*1e6};
        double tol = 1e-13, fc;
        e04ccf_(&n, x, &fc, &tol, &iw, w1, w2, w3, w4, w5, w6, &funct_MDP_, &monit_, &maxcal, &ifail);
        cout << endl << "ifail " << ifail << endl;
        cout << "x0  "<< x[0] << "et x1 " << x[1] << endl;

        return 0;
}
once
Topic archived. No new replies allowed.