我在使用 JNI 将 Fortran 代码与 Java 集成时遇到了问题。 当我将 C 对象与 Fortran 对象链接时,可能会出现问题。
文件:HelloWorld.java
public class HelloWorld {
native void foo();
static {
System.loadLibrary("test");
}
static public void main(String argv[]) {
new HelloWorld().foo();
}
}
文件:ctest.c
#include <jni.h>
#include <stdio.h>
extern void bar_();
JNIEXPORT void JNICALL Java_HelloWorld_foo
(JNIEnv * env, jobject jobj)
{
printf("Hello World!\n");
}
编译:
$ gcc -fPIC -shared -lc \
-I/usr/lib/jvm/java-7-oracle/include \
-I/usr/lib/jvm/java-7-oracle/include/linux \
-o libtest.so ctest.c
$ javac HelloWorld.java
$ java HelloWorld
Hello World!
非常好,Hello World!
工作正常。
但是当我添加 Fortran 代码时,Java 抛出异常。
文件:ftest.f95
subroutine bar()
return
end
编译:
$ gcc -fPIC -shared -lc \
-I/usr/lib/jvm/java-7-oracle/include \
-I/usr/lib/jvm/java-7-oracle/include/linux \
-o ctest.o ctest.c
$ gfortran -c ftest.f95
$ gcc -shared ftest.o ctest.o -o libtest.so
$ javac HelloWorld.java
$ java HelloWorld
Exception in thread "main" java.lang.UnsatisfiedLinkError: HelloWorld.foo()V
at HelloWorld.foo(Native Method)
at HelloWorld.main(HelloWorld.java:7)
我做错了什么?
最佳答案
一些事情:
- 对于 C 对象的构建,您不应指定
-shared
。您不是在生成独立的库。相反,使用-c
来编译对象:
gcc -fPIC -lc \
-I/usr/lib/jvm/java-7-oracle/include \
-I/usr/lib/jvm/java-7-oracle/include/linux \
-o ctest.o -c ctest.c
- 如果您想将 C 和 Fortran 对象链接在一起,您需要在这两种情况下和链接库时指定
-fPIC
。此外,您需要针对libgfortran
进行链接:
gfortran -fPIC -c ftest.f95
gcc -fPIC -shared ftest.o ctest.o -o libtest.so -lgfortran
- 您需要扩展
java.library.path
以便 JVM 可以找到库:
javac HelloWorld.java
java -Djava.library.path="$PWD" HelloWorld
使用这些命令,您的代码在我的机器上运行良好。
关于java - 通过 JNI 将 Fortran 代码与 Java 集成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33857136/