Mail Archives: cygwin/2011/04/13/12:55:02
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.<clinit>(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
- Raw text -