You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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里的实际函数。

解决方法有两种,选一个就行:

  1. 修改C桥接文件的声明:
    先查看Fortran DLL导出的函数名(用dumpbin /exports Fifp.dll命令,或者用Dependency Walker工具),比如查到是reset_,就把声明改成:
    extern void reset_();
    
  2. 修改Fortran代码指定C风格命名:
    如果能改Fortran源码,给函数加上BIND(C)属性,强制使用C的命名规则,比如:
    subroutine RESET() bind(C, name='RESET')
        ! 你的Fortran函数逻辑
    end subroutine RESET
    
    这样编译出来的DLL里,函数名就是大写的RESET,和你C里的声明完全匹配。
三、编译桥接文件成可用的DLL

你需要把myBridge.c编译成和JDK、Fortran DLL位数一致的动态链接库(比如都是64位),步骤如下:

  1. 确保你有对应位数的C编译器(比如MSVC、MinGW)。
  2. 编译时要引入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调用的正确姿势
  1. 库文件加载的问题:
    你的Java代码里写的是System.loadLibrary("Fifp"),但其实native方法的实现是在myBridge.dll里,所以应该加载桥接库,而Fortran的Fifp.dll会被桥接库自动加载:

    static { 
        // 加载桥接库,它会自动依赖加载Fifp.dll
        System.loadLibrary("myBridge"); 
    }
    

    同时要把Fifp.dll和myBridge.dll放到Java能找到的路径(比如项目根目录,或者系统PATH环境变量里)。

  2. 完整的测试类代码:
    给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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:51:14