X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,TW_UU,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org To: cygwin AT cygwin DOT com From: Hans Horn Subject: Re: 64bit (g)fortran JNI Date: Wed, 13 Apr 2011 09:54:26 -0700 Lines: 159 Message-ID: References: <4DA509A0 DOT 5070702 AT frontier DOT com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.15) Gecko/20110303 Thunderbird/3.1.9 In-Reply-To: <4DA509A0.5070702@frontier.com> X-IsSubscribed: yes Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com On 4/12/2011 7:25 PM, Jerry DeLisle wrote: > On 04/12/2011 07:38 AM, Hans Horn wrote: >> Folks, >> >> has anybody got any experience interfacing (g)fortran routines with >> Java via JNI? >> >> I'm on 64bit Windows7 using cygwin >> x86_64-w64-mingw32-gcc and x86_64-w64-mingw32-gfortran, both v4.5.2 >> >> Java: jdk-6u24-windows-x64 >> >> Even though I can statically link the JNI code successfully (using >> gfortran as >> linker), calling any native method from Java crashes the JVM - even >> when no >> fortran code is called at all. >> > What do you mean by native method? Are you trying to call Fortran > procedures from Java? > > In what way does it crash? Can you get a back trace from a debugger? > > Jerry > > PS I have no experience with this, just asking some questions to glean > additional information. Fortran calling conventions are no exactly the > same as C. Ok, > What do you mean by native method? Are you trying to call Fortran > procedures from Java? Nope, via a C wrapper. I condensed things to the simplest possible testcase that still does not function. In the process I figured that I needed to link with '-shared'. Without that I get said crash of the JVM in both cases, with or without calling fortran. here's my fortran routine: ------------------------------------------------ subroutine f77sub(string) character*(*) string write(*,*) 'string is ',string call fflush(6) end here's the JNI C wrapper that calls the fortran routine: ------------------------------------------------ #include "JNItest.h" #ifdef F77SUB void f77sub(char*, int); #endif JNIEXPORT void JNICALL Java_JNItest_java2C2f77 (JNIEnv* env, jclass obj) { #ifdef F77SUB printf("calling fortran\n"); fflush(stdout); f77sub("here is fortran", 15); printf("back from fortran\n"); fflush(stdout); #else printf("not calling fortran at all\n"); fflush(stdout); #endif } here's my Java class calling the JNI C wrapper: ------------------------------------------------ class JNItest { private native void java2C2f77 (); static { System.loadLibrary("jnitest"); } public static void main (String[] args) { new JNItest().java2C2f77(); } } here's the makefile used to compile the jnitest.dll: ------------------------------------------------ gcc_opt = -O3 -std=c99 -DCYGWIN -Wl,--kill-at \ -fno-omit-frame-pointer -I${JAVA_HOME}/include/win32 \ -I${JAVA_HOME}/include -Wall -D_JNI_IMPLEMENTATION_ gcc = gcc gfc = gfortran gfc_opt = -O3 -fno-underscoring -fno-f2c -W -Wunused \ -Wuninitialized -fno-omit-frame-pointer ld_opt = -luuid -lole32 -fno-omit-frame-pointer -shared ifeq ($(PROCESSOR_ARCHITEW6432), AMD64) #use mingw 64bit cross compilers gcc_opt += -m64 gcc = x86_64-w64-mingw32-gcc gfc = x86_64-w64-mingw32-gfortran gfc_opt += -m64 ld_opt += -m64 endif ######################################################################## allnof: jnitest_h jnitestnof; jnitest_h: JNItest.class; javah -classpath ./ JNItest jnitestnof: JNItest.c JNItest.h; \ ${gcc} ${gcc_opt} JNItest.c ${ld_opt} -o jnitest.dll ######################################################################## # attempt to call fortran from JNI code; must link with gfortran else # we're mssing fortran runtime libs, eg. _gfortran_st_write allf: f77o jnitest_h jnitestf; f77o: f77sub.o; ${gfc} ${gfc_opt} -c f77sub.f -o f77sub.o jnitestf: JNItest.c JNItest.h; \ ${gcc} -DF77SUB ${gcc_opt} -c JNItest.c -o JNItest.o; \ ${gfc} ${ld_opt} JNItest.o f77sub.o -o jnitest.dll -------------------------------------------------------------------------- the dll built w/o calling fortran (-DF77SUB not set; make jnitestnof) prints (as it should): "not calling fortran at all" --------------------------------------------------------------------------- the dll built with calling fortran (-DF77SUB set; make jnitestf, gfortran as linker) is expected to print: calling fortran here is fortran back from fortran however, it produces an unsatisfied link error such as: java.lang.UnsatisfiedLinkError: D:\native\jnitest.dll: %1 is not a valid Win32 application at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1803) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1728) at java.lang.Runtime.loadLibrary0(Runtime.java:823) at java.lang.System.loadLibrary(System.java:1028) at JNItest.(JNItest.java:4) Note that the path to the gfortran runtime is included in the Windows PATH variable: PATH=D:\native;C:\CygWin\usr\i686-w64-mingw32\sys-root\mingw\bin;... Thx., H. -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple