java - 通过 JNI 将 Fortran 代码与 Java 集成

标签 java c java-native-interface fortran gfortran

我在使用 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/

相关文章:

java - HTML 电子邮件的隐藏/显示按钮

c - 禁用 DSUSP - 终端控制

java - JNI 从 DWord 返回值

android - 在 JNI Android 中写入标准输出?没有 <android/log.h>

java-native-interface - 带有 JNI 的 C++ 应用程序抛出错误 "jvm.dll not found . re-installing the application could fix ...."

java - Java Swing 中的 PNG 渲染错误(颜色深度低)

Java ANTLR 如何忽略部分规则?忽略子规则后的部分

java - Tomcat 8 无法通过 Ant 脚本部署

c - wchar_t 到八位字节 - 在 C 中?

C语言凯撒密码