bigbear

          2010年5月12日 #

          JNA實現(xiàn)Java調(diào)用Fortran(f77)

          在成功實現(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)用,所以費(fèi)了一些周折。

          問題的關(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ù)。

          運(yùn)行程序,得到如下結(jié)果:

          run:
           SUB1 CALLED
           1234
          成功生成(總時間:1 秒)

          3、G95的調(diào)用更簡單一些,可以直接使用bind指定輸出過程(函數(shù))名,可以完全不必考慮編譯器的命名規(guī)則,比f77的方式可移植性更好一些。

          可以參考這里:http://www.javaforge.com/wiki/66061

          posted @ 2010-05-12 22:05 大熊 閱讀(3090) | 評論 (0)編輯 收藏

          2010年5月11日 #

          JNA實現(xiàn)Java調(diào)用C++動態(tài)鏈接庫

          今天偶然看到了JNA的介紹,下載下來試了一下,很好用,相比較JNI要簡單很多。做了一個可以callback的c++動態(tài)鏈接庫,實現(xiàn)了java和c++的互相調(diào)用。

           1、開發(fā)環(huán)境:

           開發(fā)工具:Netbeans 6.8,包含了Java和C++開發(fā)插件,用一個工具比較方便,可以同時開發(fā)C++的dll和Java代碼。

          C++環(huán)境:MingW 5.1.6+MSYS、g++ 3.4.5

          Java環(huán)境:JDK 1.6.0_18

           2、C++代碼

           用Netbeans創(chuàng)建一個動態(tài)鏈接庫項目JNALib,創(chuàng)建一個c++源文件clib.cpp,生成結(jié)果為libJNALib.dll

           #include <stdlib.h>
          #include 
          <iostream>
          using namespace std;
          extern "C"
          {
              typedef 
          void (*OpenFunc)(const char*,int);

              OpenFunc openfunc 
          = NULL;

              
          void init(OpenFunc func) {
                  cout 
          << "init called" <<endl;
                  openfunc 
          = func;
              }


              
          void test() {
                  
          if (openfunc == NULL) {
                      cout 
          << "openfunc is NULL" << endl;
                  }

                  (
          *openfunc)("test"0);
              }

          }

           

          注意:其中OpenFunc聲明了一個回調(diào)類型,也就是一個函數(shù)指針,可以通過init將java中的OpenFunc方法傳遞進(jìn)來,設(shè)置這個函數(shù)指針,如此一來,可以實現(xiàn)C++到Java的回調(diào)。

           3、Java代碼

           創(chuàng)建一個Java項目JNADemo,創(chuàng)建一個包clibtest,創(chuàng)建以下java代碼:

           

          package clibtest;

          import com.sun.jna.Callback;
          import com.sun.jna.Library;


          public interface CLib extends Library{

              
          public interface OpenFunc extends Callback {
                  
          void invoke(String filename, int i);
              }

              
          void init(OpenFunc openfunc);
              
          void test();
          }



           

          package clibtest;

          import com.sun.jna.Native;

          public class hello {

              
          public static void main(String[] args) {
                  
          // Loading dynamically the library
                  CLib lib = (CLib) Native.loadLibrary("libJNALib", CLib.class);

                  lib.init(
          new CLib.OpenFunc() {

                      
          public void invoke(String filename, int i) {
                          System.out.println(
          "callback called.");
                          System.out.println(filename);
                      }

                  }
          );

                  lib.test();
              }

          }


           

          4、項目結(jié)構(gòu)如下



          5、編譯C++項目,生成libJNALib.dll,拷貝到JNADemo主目錄,目錄結(jié)構(gòu)如下:

          6、運(yùn)行程序,結(jié)果如下:

          posted @ 2010-05-11 10:51 大熊 閱讀(4691) | 評論 (1)編輯 收藏

          僅列出標(biāo)題  
          主站蜘蛛池模板: 谷城县| 万年县| 娄烦县| 南昌县| 原平市| 浪卡子县| 明光市| 驻马店市| 疏勒县| 昭苏县| 平安县| 页游| 香港 | 桦川县| 康平县| 克什克腾旗| 清苑县| 建德市| 屯留县| 汽车| 留坝县| 色达县| 南安市| 酉阳| 花莲市| 花垣县| 满洲里市| 左权县| 施秉县| 抚顺市| 榆中县| 伊春市| 象州县| 拜城县| 岱山县| 莱芜市| 壤塘县| 亚东县| 裕民县| 白沙| 九龙县|