使用JNI从Java调用Fortran编写的Fifp.dll中RESET()函数的问题
嘿,我来帮你搞定这个JNI调用Fortran DLL的问题,先梳理下整个流程和你当前代码里的坑:
一、先修正现有代码的小问题
你的myBridge.c最后一行代码没写完,而且函数没有闭合,会导致编译报错,修正后应该是这样:
#include <stdio.h> #include "TestJni.h" // 注意:这里的函数名可能需要和Fortran DLL导出的实际名字匹配,后面会讲 extern void RESET(); JNIEXPORT void JNICALL Java_TestJni_RESET(JNIEnv *env, jobject obj) { printf("Before DLL call\n"); RESET(); printf("After DLL call\n"); }
二、最容易踩的坑:Fortran函数的命名修饰
Fortran编译器编译DLL时,会对函数名做自动修饰,这是JNI调用失败的重灾区:
- 比如Intel Fortran、gfortran这类编译器,默认会把大写的
RESET()转成小写,还可能加下划线,变成reset_或者reset(具体取决于编译器的选项)。 - 这就导致你C代码里的
extern void RESET();根本找不到DLL里的实际函数。
解决方法有两种,选一个就行:
- 修改C桥接文件的声明:
先查看Fortran DLL导出的函数名(用dumpbin /exports Fifp.dll命令,或者用Dependency Walker工具),比如查到是reset_,就把声明改成:extern void reset_(); - 修改Fortran代码指定C风格命名:
如果能改Fortran源码,给函数加上BIND(C)属性,强制使用C的命名规则,比如:
这样编译出来的DLL里,函数名就是大写的subroutine RESET() bind(C, name='RESET') ! 你的Fortran函数逻辑 end subroutine RESETRESET,和你C里的声明完全匹配。
三、编译桥接文件成可用的DLL
你需要把myBridge.c编译成和JDK、Fortran DLL位数一致的动态链接库(比如都是64位),步骤如下:
- 确保你有对应位数的C编译器(比如MSVC、MinGW)。
- 编译时要引入JDK的头文件(
jni.h和jni_md.h,在JDK的include和include/win32目录下),还要链接Fifp.dll作为依赖。
举个MSVC的命令例子:
这里cl -I"C:\Program Files\Java\jdk1.8.0_291\include" -I"C:\Program Files\Java\jdk1.8.0_291\include\win32" -LD myBridge.c Fifp.dll -o myBridge.dll-LD表示编译成动态链接库,-o指定输出的桥接DLL名字,Fifp.dll是要依赖的Fortran库。
四、Java调用的正确姿势
库文件加载的问题:
你的Java代码里写的是System.loadLibrary("Fifp"),但其实native方法的实现是在myBridge.dll里,所以应该加载桥接库,而Fortran的Fifp.dll会被桥接库自动加载:static { // 加载桥接库,它会自动依赖加载Fifp.dll System.loadLibrary("myBridge"); }同时要把
Fifp.dll和myBridge.dll放到Java能找到的路径(比如项目根目录,或者系统PATH环境变量里)。完整的测试类代码:
给TestJni加个main方法,方便测试调用:public class TestJni { static { System.loadLibrary("myBridge"); } public native void RESET(); public static void main(String[] args) { new TestJni().RESET(); } }
五、常见问题排查
如果遇到报错,按下面的思路排查:
- UnsatisfiedLinkError:
- 检查所有库文件的位数是否和JDK一致(32位JDK不能用64位DLL,反之亦然)。
- 用
javap -s TestJni查看native方法的签名,确保Java_TestJni_RESET的参数、返回值完全匹配。 - 再次确认Fortran DLL的导出函数名和C里的extern声明一致。
- 运行时找不到Fifp.dll:
- 把
Fifp.dll放到和myBridge.dll同目录,或者加到系统PATH里。
- 把
内容的提问来源于stack exchange,提问作者Tierce
相关产品推荐
相关产品推荐

