java调用fortran 77的dll Exception in thread “main” java.lang.UnsatisfiedLinkError: Error looking up fun

  • Post author:
  • Post category:java


注意一点:

调用函数java里面的fortran函数名字要全部大写!!!!

本文使用的是java 的JNA实现对fortran dll的调用,所以你需要先安装JNA库。

第一次java调用fortran的dll时,总是报错 Exception in thread “main” java.lang.UnsatisfiedLinkError: Error looking up function ‘ap8ae8’: 找不到指定的程序。后来看网上(

http://blog.sina.com.cn/s/blog_4ed144110102wnqh.html

)说是问题的关键在于F77为过程名自动添加了一个尾部的下划线,所以fortran 里面定义的sub1()子程序,在java里面要改成sub1_()。我深以为然,结果改过来依然报同样的错误。网上找了很多材料,还是没有解决问题。

后来我在网上找C++调用fortran 的dll 的成功例子时,意外发现fortran里面的函数名称是小写的,但C++里面调用的函数名字是大写的。我赶紧把java里面的调用函数名称大写,结果成功了!

附上部分fortran 代码:

ap8ae8.f90

!

!  FUNCTIONS/SUBROUTINES exported from ap8ae8.dll:

!  ap8ae8 – subroutine

!

subroutine ap8ae8(OutputFileName,lenOfOutputFileName,

1coordType,

1L_FROMFILE_Start,L_FROMFILE_End, L_FROMFILE_Gap,

1BB0_FROMFILE_Start,BB0_FROMFILE_End,BB0_FROMFILE_Gap,xlatStart,

1xlatEnd,xlatGap,xlongStart,xlongEnd,xlongGap,yearStart,yearEnd,

1yearGap,heightStart,heightEnd,heightGap, MODEL, FLUXTYPE, E1, E2)

! Expose function apae20151108flux to users of this DLL

!


!DEC$ ATTRIBUTES DLLEXPORT::ap8ae8

! Variables

! Body of apae20151108flux

real L_FROMFILE_Start,L_FROMFILE_End, L_FROMFILE_Gap,

1BB0_FROMFILE_Start,BB0_FROMFILE_End,BB0_FROMFILE_Gap,

1xlatStart,xlatEnd,xlatGap,xlongStart,xlongEnd,xlongGap,

1yearStart,yearEnd,yearGap,heightStart,

1heightEnd,heightGap,  E1, E2

integer coordType,MODEL, FLUXTYPE

CHARACTER, dimension(*), intent(in) :: OutputFileName

CHARACTER(len=lenOfOutputFileName):: FNM

INTEGER :: lenFNM

do i=1,lenOfOutputFileName

FNM(i:i)=OutputFileName(i)

end do

call ap8ae8main(OutputFileName,lenOfOutputFileName,coordType,

1L_FROMFILE_Start,L_FROMFILE_End, L_FROMFILE_Gap,

1BB0_FROMFILE_Start,BB0_FROMFILE_End,BB0_FROMFILE_Gap,xlatStart,

1xlatEnd,xlatGap,xlongStart,xlongEnd,xlongGap,yearStart,yearEnd,

1yearGap,heightStart,heightEnd,heightGap, MODEL, FLUXTYPE, E1, E2)

write(*,*)”hello!”

end subroutine

subroutine ap8ae8main(OutputFileName,lenOfOutputFileName,

1coordType,L_FROMFILE_Start,L_FROMFILE_End, L_FROMFILE_Gap,

1BB0_FROMFILE_Start,BB0_FROMFILE_End,BB0_FROMFILE_Gap,xlatStart,

1xlatEnd,xlatGap,xlongStart,xlongEnd,xlongGap,yearStart,yearEnd,

1yearGap,heightStart,heightEnd,heightGap, MODEL, FLUXTYPE, E1, E2)

real L_FROMFILE_Start,L_FROMFILE_End, L_FROMFILE_Gap,

1BB0_FROMFILE_Start,BB0_FROMFILE_End,BB0_FROMFILE_Gap,xlatStart,

1xlatEnd,xlatGap,xlongStart,xlongEnd,xlongGap,yearStart,yearEnd,

1yearGap,heightStart,heightEnd,heightGap

real L_FROMFILE, BB0_FROMFILE,  E1, E2,FLUX1,YEAR,LATI,LONGI,HEIGHT

integer MODEL, FLUXTYPE,coordType

CHARACTER, dimension(*), intent(in) :: OutputFileName

CHARACTER(len=lenOfOutputFileName):: FNM

INTEGER :: lenFNM

do i=1,lenOfOutputFileName

FNM(i:i)=OutputFileName(i)

end do

IF(coordType.EQ.1) THEN

OPEN(UNIT=10,FILE=FNM,  status=”replace”,access=’append’,

1FORM=’FORMATTED’)

WRITE(10,90000)

…………

注意:

!DEC$ ATTRIBUTES DLLEXPORT::ap8ae8   里面的ap8ae8名字必须与subroutine ap8ae8()名字相同

,但与.for文件的名字无关

成功调用的java代码:

(1)接口代码FLib.java

import com.sun.jna.Library;

import com.sun.jna.ptr.ByReference;

public interface FLib extends Library {


void ap8ae8(String OutputFileName,ByReference lenOfOutputFileName, ByReference coordType,ByReference L_FROMFILE_Start,ByReference L_FROMFILE_End, ByReference L_FROMFILE_Gap,ByReference BB0_FROMFILE_Start,ByReference BB0_FROMFILE_End,ByReference BB0_FROMFILE_Gap,ByReference xlatStart,ByReference xlatEnd,ByReference xlatGap,ByReference xlongStart,ByReference xlongEnd,ByReference xlongGap,ByReference yearStart,ByReference yearEnd,ByReference yearGap,ByReference heightStart,ByReference heightEnd,ByReference heightGap,ByReference  MODEL, ByReference FLUXTYPE, ByReference E1,ByReference  E2);

}

(2)调用代码Main.java

import com.sun.jna.Native;

import com.sun.jna.ptr.IntByReference;

import com.sun.jna.ptr.DoubleByReference;

import com.sun.jna.ptr.FloatByReference;

public class Main {

public static void main(String[] args) {


// Loading dynamically the library

FLib lib2=(FLib) Native.loadLibrary(“D:\\Project\\eclipse\\apaetest\\bin\\ap8ae8.dll”, FLib.class);

String  OutputFileName = “D:\\TEST.txt”;

IntByReference lenOfOutputFileName=new IntByReference(OutputFileName.length());

IntByReference MODEL=new IntByReference(1);

IntByReference coordType=new IntByReference(1);

IntByReference FLUXTYPE=new IntByReference(1);

FloatByReference L_FROMFILE_Start=new FloatByReference(1);

FloatByReference L_FROMFILE_End=new FloatByReference(2);

FloatByReference L_FROMFILE_Gap=new FloatByReference(1);

FloatByReference BB0_FROMFILE_Start=new FloatByReference(1);

FloatByReference BB0_FROMFILE_End=new FloatByReference(2);

FloatByReference BB0_FROMFILE_Gap=new FloatByReference(1);

FloatByReference xlatStart=new FloatByReference(1);

FloatByReference xlatEnd=new FloatByReference(2);

FloatByReference xlatGap=new FloatByReference(1);

FloatByReference xlongStart=new FloatByReference(1);

FloatByReference xlongEnd=new FloatByReference(2);

FloatByReference xlongGap=new FloatByReference(1);

FloatByReference yearStart=new FloatByReference(1);

FloatByReference yearEnd=new FloatByReference(2);

FloatByReference yearGap=new FloatByReference(1);

FloatByReference heightStart=new FloatByReference(1);

FloatByReference heightEnd=new FloatByReference(2);

FloatByReference heightGap=new FloatByReference(1);

FloatByReference E1=new FloatByReference(1);

FloatByReference E2=new FloatByReference(1);

lib2.ap8ae8(OutputFileName,lenOfOutputFileName,coordType,

L_FROMFILE_Start,L_FROMFILE_End, L_FROMFILE_Gap,

BB0_FROMFILE_Start,BB0_FROMFILE_End,BB0_FROMFILE_Gap,xlatStart,

xlatEnd,xlatGap,xlongStart,xlongEnd,xlongGap,yearStart,yearEnd,

yearGap,heightStart,heightEnd,heightGap, MODEL, FLUXTYPE, E1, E2);

}

}

成功调用dll里面的ap8ae8函数时将会看到输出“hello!”

另外:关于!DEC$,这篇文章里面提到

https://blog.csdn.net/fengyhack/article/details/8594727

以上!DEC$打头的两行,如第一个,其另一形式如下

!MS$IF .NOT. DEFINED(LINKDIRECT)

!MS$ATTRIBUTES DLLEXPORT::FACT

!MS$ENDIF

可分别替换之,而余下代码都是一样的。



版权声明:本文为zhuiyuanzhongjia原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。