Очень интересная статья! Меня тоже интересует возможность/удобство такой связки, как Java(GUI)+Fortran(Computation). Сразу у меня ничего не захотело работать из того, что там дается в качестве исходников. Но вроде удалось разобраться, как создавать dll с кодом фортрана, чтобы ее понимала программа на Java. Идея создания такой dll там кратко описана: вызовы делаются из Java к C++, а от C++ к Fortran. При этом часть C++ & Fortran можно запихать в одну dll. Я пользуюсь пока Compaq Visual Fortran и Visual C++ 6.0. Делал так:
1. Часть, которая там написана на Java я нисколько не менял. 2. Это код на c++, его пришлось немного поменять (передача скалярных параметров не через укзатели, а напрямую):
| Код | #include <jni.h> #include "TempCalcJava.h" // //################################################################### // TempCalcJava.cpp //################################################################### // // // Creator : Chris Anderson // (C) UCLA 1997 7/16/97 // // // To have this code call the FORTRAN versions; define __FORTRAN_BUILD__ // when compiling. // Typically this is specified by -D __FORTRAN_BUILD__ as part of the C++ // compilation command (Unix) or as a project setting when working within // an integrated development environment. // //################################################################### //
extern "C" void inittemp(double* tPtr, long m, long n, double a, double b, double c, double d);
extern "C" void evtemp(double* tPtr, long m, long n, double a, double b, double c, double d, double dt, double diffusivity, double* wPtr);
JNIEXPORT void JNICALL Java_TempCalcJava_initializeTemperature (JNIEnv *env, jobject, jdoubleArray Tarray, jint m, jint n, jdouble a, jdouble b, jdouble c, jdouble d) { jdouble* tPtr = env->GetDoubleArrayElements(Tarray,0);
inittemp(tPtr, m, n, a, b, c, d);
env->ReleaseDoubleArrayElements(Tarray, tPtr,0); };
JNIEXPORT void JNICALL Java_TempCalcJava_evolveTemperature (JNIEnv *env, jobject, jdoubleArray Tarray, jint m, jint n, jdouble a, jdouble b, jdouble c, jdouble d, jdouble dt, jdouble diffusivity, jdoubleArray workArray) {
jdouble* tPtr = env->GetDoubleArrayElements(Tarray,0); jdouble* wPtr = env->GetDoubleArrayElements(workArray,0);
evtemp(tPtr, m, n, a, b, c, d, dt, diffusivity, wPtr);
env->ReleaseDoubleArrayElements(Tarray, tPtr,0); env->ReleaseDoubleArrayElements(workArray, wPtr,0); };
|
Файл TempCalcJava.h менять не нужно.
3. Теперь код на Fortran, изменил только директивы компилятора (!DEC$...):
| Код | ! !################################################################### ! tempCalcRoutines.f !################################################################### ! ! Creator : Chris Anderson ! (C) UCLA 1997 7/16/97 ! !################################################################### ! subroutine inittemp(T, m, n, a, b, c, d) !DEC$ ATTRIBUTES C, ALIAS:'_inittemp' :: inittemp implicit real*8 (a-h,o-z) integer*4 m,n real*8 T(m,n)
hx = (b-a)/(m-1.0) hy = (d-c)/(n-1)
do 50 i = 1,m x = a + i*hx do 50 j = 1,n y = c + j*hy T(i,j) = sin(4.0d00*x*y) 50 continue
do 75 i = 1,m T(i,1) = 0.0 T(i,n) = 0.0 75 continue
do 100 j = 1,n T(1,j) = 0.0 T(m,j) = 0.0 100 continue
return end
subroutine evtemp(T, m, n, a, b, c, d, dt, diffusivity, W) !DEC$ ATTRIBUTES C, ALIAS:'_evtemp' :: evtemp implicit real*8 (a-h,o-z) integer*4 m,n real*8 T(m,n) real*8 W(m,n) ! ! Evolve using Forward Euler timestepping ! hx = (b-a)/(m-1) hy = (d-c)/(n-1)
do 100 i = 2,m-1 do 100 j = 2,n-1 W(i,j) = diffusivity*dt*& (((T(i+1,j) - 2.0*T(i,j) + T(i-1,j))/(hx*hx)) +& ((T(i,j+1) - 2.0*T(i,j) + T(i,j-1))/(hy*hy))) 100 continue
do 200 i = 1,m do 200 j = 1,n T(i,j) = T(i,j) + W(i,j) 200 continue
return end
|
Собирается так (предполагается, что TempCalcJava.cpp, TempCalcJava.h, tempCalcRoutines.f лежат в одной директории, что пути до include для java и lib для fortran и c++ указаны в переменных окружения): 1. Компилируем код на Fortran: df /compile_only tempCalcRoutines.f 2. Компилируем код на c++: cl /c TempCalcJava.cpp 3. Собираем все в dll: link /dll TempCalcJava.obj tempCalcRoutines.obj
В результате получается одна dll, из которой экспортируются только фунции для взаимодействия с Java. Осталось только собрать Java приложение из статьи и скопировать полученную dll. |