Appels croisés fortran, c, c++
Bonjour à tous.
Voici mon problème :
Je dois, à partir d'un programme principal en fortran, appeler une fonction c++, qui elle-même appelle une subroutine fortran du programme principal.
Je code sous linux et après quelques tours sur des forums sur le sujet j'ai cru comprendre que le plus simple était de passer par du C.
Mon architecture est donc la suivante :
le programme fortran appelle une fonction C, qui elle-même appelle une fonction c++, qui elle-même appelle une subroutine fortran.
Et y'a un soucis à la compilation.
Voici les squelettes de mes codes :
Fortran (fonction.f) :
Code:
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
| program fortran
end
recursive &
subroutine solveur (fcn, x, tolerance, code_sortie)
! arguments
interface
subroutine fcn (n, m, x, fvec, iflag)
integer :: n
integer :: m
real, dimension (1:3) :: x(n)
real, dimension (1:3) :: fvec(m)
integer :: iflag
end subroutine fcn
end interface
real, dimension (1:3) :: x(:)
real, dimension (1:3) :: tolerance
integer, intent(out) :: code_sortie
! appel
call interface_n(n, m, x, tolerance, code_sortie)
end subroutine solveur |
Le C (module.c):
Code:
1 2 3 4 5 6 7 8 9
| #include <stdlib.h>
#include <stdio.h>
extern void n_cpp(int, int, float*, int, int);
void interface_n(int n, int m, float *x, int tolerance, int code_sortie)
{
nomad_cpp(n, m, x, tolerance, code_sortie);
} |
Et le c++ (n_cpp):
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include <iostream>
#include <fstream>
using namespace std;
extern "C"
{
void n_cpp(int, int, float*, int, int);
void fcn_(int*, int*, float*, float*, int*);
}
void n_cpp(int n, int m, float *x, int tolerance, int code_sortie)
{
float fvec[m];
int iflag = -1;
fcn_(&n, &m, x, fvec, &iflag);
} |
Bien sûr ces codes sont bidons, c'est juste pour essayer de faire fonctionner ces "appels croisés".
Je compile tout ça avec :
Code:
1 2 3 4
| % gfortran -c -ffree-form fonction.f
% gcc -c module.c
% g++ -c n_cpp.cpp
% gfortran -o fonction.o module.o n_cpp.o |
Et voici l'erreur :
Code:
1 2 3 4 5 6 7 8 9
| n_cpp.o: In function `__static_initialization_and_destruction_0(int, int)':
n_cpp.cpp:(.text+0x1d): undefined reference to `std::ios_base::Init::Init()'
n_cpp.cpp:(.text+0x22): undefined reference to `std::ios_base::Init::~Init()'
n_cpp.o: In function `nomad_cpp':
n_cpp.cpp:(.text+0x185): undefined reference to `fcn_'
n_cpp.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
/usr/lib/gcc/i586-suse-linux/4.3/libgfortranbegin.a(fmain.o): In function `main':
(.text+0x35): undefined reference to `MAIN__'
collect2: ld a retourné 1 code d'état d'exécution |
En tapant ces erreurs dans Google (qui est mon ami) j'ai trouvé comme raison des programmes c++ compilés avec gcc au lieu de g++.
J'ai donc essayé de compiler mon code c avec g++, modulo une toute petite modif au niveau de la déclaration de
Code:
extern void n_cpp(int, int, float*, int, int);
qui devient
Code:
1 2
| extern "C"
{ void n_cpp(int, int, float*, int, int);} |
mais les erreurs restent les mêmes...
Et je bloque...
Est-ce que quelqu'un pourrait m'aider sioupl ?
Est-ce que les appels croisés que je fais sont tout simplement impossibles ?
Ou est-ce que je fais une erreur lors de l'éditions des liens ?
Ou autre chose encore ?
Merci beaucoup.