在成功實現(xiàn)Java調(diào)用C++之后,接下來想到能否通過JNA實現(xiàn)Java調(diào)用Fortran,今天試驗了一下,還是比較容易的。
網(wǎng)上有一個Java調(diào)用F95的例子,但是我考慮不僅要實現(xiàn)F95的調(diào)用,還要實現(xiàn)F77的調(diào)用,所以費了一些周折。
問題的關(guān)鍵在于F77為過程名自動添加了一個尾部的下劃線,所以sub1這個過程,到Java一端,就變成了sub1_,知道了這一點,后面就簡單了。
1、創(chuàng)建一個動態(tài)鏈接庫項目FortranDLL,新建一個簡單的fortran源程序for1.f:
subroutine sub1(i)
INTEGER i;
PRINT*, "SUB1 CALLED"
PRINT*, i
END subroutine
編譯代碼生成libFortranDLL.dll。
2、新建一個Java項目,包含JNA庫
創(chuàng)建一個動態(tài)庫接口代碼FLib.java:
import com.sun.jna.Library;
import com.sun.jna.ptr.ByReference;


public interface FLib extends Library
{
void sub1_(ByReference i);
}
創(chuàng)建一個主程序Main.java
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;


public class Main
{


public static void main(String[] args)
{
// Loading dynamically the library
FLib lib2 = (FLib) Native.loadLibrary("libFortranDLL", FLib.class);
IntByReference a = new IntByReference(1234);
lib2.sub1_(a);
}
}

注意,關(guān)鍵在于接口當(dāng)中的sub_這個命名規(guī)則,否則無法找到找到指定過程,另外默認(rèn)情況下,fortran使用引用參數(shù),所以不能簡單實用int作為參數(shù),必須實用引用參數(shù)。
運行程序,得到如下結(jié)果:
run:
SUB1 CALLED
1234
成功生成(總時間:1 秒)
3、G95的調(diào)用更簡單一些,可以直接使用bind指定輸出過程(函數(shù))名,可以完全不必考慮編譯器的命名規(guī)則,比f77的方式可移植性更好一些。
可以參考這里:http://www.javaforge.com/wiki/66061