Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Fortran > [Interop] Создание GUI на Java


Автор: Cr@$h 16.7.2006, 02:19
По воли случая встретил интересную статью: "http://www.math.ucla.edu/%7Eanderson/JAVAclass/JavaInterface/JavaInterface.html#Process". Ещё не успел прочитать, но она явно описывает что-то невероятное: чтобы Java мог понимать DLL или SL от Fortran, -- это нонсанс для меня smile . Примеры есть, так что без обмана. Смущает только год -- 97, с тех времён Sun  smile  для Java могла выстроить заборы ещё выше  smile . 

Автор: kamre 4.9.2006, 18:46
Очень интересная статья! Меня тоже интересует возможность/удобство такой связки, как 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.

Автор: powerOn 4.9.2006, 21:50
А что тут особенного? http://java.sun.com/j2se/1.4.2/docs/guide/jni/ - это вполне стандартная вещь, используется и посей день для связи Java программ с нативым кодом...  smile Не вижу ничего удивительного....

Автор: Cr@$h 4.9.2006, 22:41
Цитата(MoonCat @  4.9.2006,  22:50 Найти цитируемый пост)
Не вижу ничего удивительного.... 

Цитата(kamre @  4.9.2006,  19:46 Найти цитируемый пост)
Идея создания такой dll там кратко описана: вызовы делаются из Java к C++, а от C++ к Fortran. 

Тогда согласен, конечно. Про это я знаю. Думал Java напрямую к Fortran может обращаться, а про то, что к Java можно подойти из любого места, но через С++, известно многим.
Дискуссию ещё продолжу, попозже.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)