Bonjour à tous,
Ma situation est assez spéciale, je souhaiterais faire appel à des fonctions Fortran sous Windows (compilées dans une DLL) depuis un programme Java. Pour cela j’utilise la librairie Java Native Interface. Avant tout, j'essai de commencer très simple avec le fameux programme HelloWorld. Malheureusement je n’y arrive pas et j’ai besoin de votre aide. J’ai réussi dans un premier temps à linker le Java et le C++ sans problème, mais je bloque à l’étape suivante : lecture la DLL Fortran à partir du C++
J’essai d’utiliser les compilateurs GNU open source pour réaliser cela, c'est-à-dire gcc (g++) et gfortran.
Voici les étapes que j’ai réalisée jusque la :
1- Installation de Java 6.0 et Eclipse 3.4
2- Installation de gfortran (http://gcc.gnu.org/wiki/GFortran)
3- Installation de devCpp (http://sourceforge.net/projects/dev-cpp/)
4- Création du programme HelloWorld fortran (fichier helloworld.f90)
helloworld.f90
5- Compilation du programme avec gfortran (option –c) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 program helloworld write(*,*) "Hello world!" end program helloworld
Remarque : J’ai également vu sur certain site l’option –fPIC qui était utilisée mais celle-ci n’a pas l’air d’être utile puisqu’elle génère le message suivant : f951.exe: warning: -fPIC ignored for target (all code is position independent)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2"C:\Program Files\gfortran\bin\gfortran.exe" -c D:\helloworld.f90
6- Création de la DLL toujours avec gfortran (options -Xlinker -shared –o) :
Remarque : j’ai essayé la commande avec d’autres options que j’ai pu voir :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2"C:\Program Files\gfortran\bin\gfortran.exe" -shared -o D:\helloworld.dll D:\helloworld.o
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2"C:\Program Files\gfortran\bin\gfortran.exe" -Xlinker -shared -o D:\helloworld.dll D:\helloworld.o
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2"C:\Program Files\gfortran\bin\gfortran.exe" -shared -mtrd -o D:\helloworld.dll D:\helloworld.o
Mais cela n’a pas l’air de changer quelque chose.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2"C:\Program Files\gfortran\bin\gfortran.exe" -Xlinker --add-stdcall-alias -shared -o D:\helloworld.dll D:\helloworld.o
A la suite de cette étape, j’obtiens la DLL Fortran helloworld.dll
7- Création du fichier Java FortranExecuter.java et de la méthode native helloworld()
FortranExecuter.java
8- Compilation du fichier FortranExecuter.java
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 public class FortranExecuter { private static native double helloworld(); static { System.load("D:\\FortranExecuter.dll"); } public static void main(String[] args) { FortranExecuter.helloworld(); } }
9- Génération du fichier d’entete .h avec la commande javah.exe
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 C:\j2sdk6.0.7\jdk\bin\javac.exe D:\FortranExecuter.java
10- Modification du fichier FortranExecuter.h généré en ajoutant la méthode cobol externe
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 C:\j2sdk6.0.7\jdk\bin\javah.exe -classpath D:\ -d D:\ -jni FortranExecuter
FortranExecuter.h
Remarque : dans d'autres discussions, j'ai parfois vu l'utilisation des macros __declspec (dllexport) et __stdcall devant la méthode externe, j'ai fait quelques tests mais en vain. je ne sais pas trop à quoi ces directives servent.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class FortranExecuter */ #ifndef _Included_FortranExecuter #define _Included_FortranExecuter #ifdef __cplusplus extern "C" { #endif /* * Class: FortranExecuter * Method: helloworld * Signature: ()D */ JNIEXPORT jdouble JNICALL Java_FortranExecuter_helloworld(JNIEnv *, jclass); void helloworld_(); #ifdef __cplusplus } #endif #endif
11- Création du fichier FortranExecuter.cpp
FortranExecuter.cpp
12- Compilation du programme avec g++ (option –c) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 // FortranExecuter.cpp #include <jni.h> #include <stdio.h> #include "FortranExecuter.h" JNIEXPORT jdouble JNICALL Java_FortranExecuter_helloworld(JNIEnv * env, jclass cl) { helloworld_(); }
13- Création de la DLL C toujours avec g++ (options -Xlinker --add-stdcall-alias -shared -o) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 C:\Dev-Cpp\bin\g++.exe -I"C:\j2sdk6.0.7\jdk\include" -I"C:\j2sdk6.0.7\jdk\include\win32" -c D:\FortranExecuter.cpp -o D:\FortranExecuter.o
Cette commande génère l’érreur de lien suivante me disant qu’il ne trouve pas la fonction helloworld :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 C:\Dev-Cpp\bin\g++.exe -Xlinker --add-stdcall-alias -shared -o D:\FortranExecuter.dll D:\FortranExecuter.o
Remarque : j’ai essayé de déplacer la DLL fortran dans les fichiers systèmes mais sans résultat. J’ai également essayé certaines options mais j’ai peur qu’il manque quelquechose dans ma démarche.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 D:\FortranExecuter.o(.text+0x7):FortranExecuter.cpp: undefined reference to `helloworld_' collect2: ld returned 1 exit status
Auriez vous des conseils / idées afin de faire marcher le lien ? Je n'ai trouvé aucun tutoriel viable sur le net et j'ai également consulté certaines autres discussions sur ces pages :
http://www.developpez.net/forums/d34...fortran-c-cpp/
http://www.developpez.net/forums/d63...ant-creer-dll/
http://www.developpez.net/forums/d37...n-fortran-cpp/
Partager