天天看點

JAVA調用動态連結庫DLL之JNative學習如何捕獲 System.loadLibrary 産生的異常?

JAVA調用動态連結庫DLL的方法有:JNI(Java Native Interface),JInvoke,JNative(Java to native interface),JNI是JAVA自身提供的方法;JInvoke從何而來不得而知,好像還需要注冊付費的,64位的JDK、JIR環境下運作不了,在VMware下安裝的WindowsXP下同樣有問題;JNative是開源的,但相關資料文檔也特别的少,好像已經停止更新了。JNative源碼位址:http://jnative.cvs.sourceforge.net/viewvc/jnative/,jar包下載下傳位址:http://sourceforge.net/projects/jnative/files/jnative/。

開發環境:myeclipse-10.7-offline-installer-windows

檔案》建立》JAVA項目:

JAVA調用動态連結庫DLL之JNative學習如何捕獲 System.loadLibrary 産生的異常?

輸入項目名稱,單擊“Finish”:

JAVA調用動态連結庫DLL之JNative學習如何捕獲 System.loadLibrary 産生的異常?

單擊滑鼠右鍵》建立》類:

JAVA調用動态連結庫DLL之JNative學習如何捕獲 System.loadLibrary 産生的異常?

輸入包名,類名,勾選“public static void main(String[] args)”,單擊“Finish”:

JAVA調用動态連結庫DLL之JNative學習如何捕獲 System.loadLibrary 産生的異常?

打開項目檔案目錄:

JAVA調用動态連結庫DLL之JNative學習如何捕獲 System.loadLibrary 産生的異常?

将要調用的DLL檔案“EhfscliaxDll.dll”複制到此目錄下,該DLL的代碼請參考:VS2010編寫動态連結庫DLL及單元測試用例,調用DLL測試正确性

建立“lib”檔案夾,将JNative.jar複制到此目錄下:

JAVA調用動态連結庫DLL之JNative學習如何捕獲 System.loadLibrary 産生的異常?

配置編譯目錄:

JAVA調用動态連結庫DLL之JNative學習如何捕獲 System.loadLibrary 産生的異常?

單擊“Add External JARs”添加jar包,下圖為已經添加過的:

JAVA調用動态連結庫DLL之JNative學習如何捕獲 System.loadLibrary 産生的異常?

Helper類代碼:

package com.ehfscliax;

import org.xvolks.jnative.JNative;  
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;  
import org.xvolks.jnative.pointers.Pointer;

public class Helper {
	/**
	 * @param args
	 * @throws NativeException 
	 */
	public static void main(String[] args) throws NativeException {
		
		JNative.setLoggingEnabled(true);
		try {
			JNative getUrl = new JNative("EhfscliaxDll.dll", "getUrl"); //建立 getUrl 方法的JNative對象
			getUrl.setRetVal(Type.STRING); //設定傳回值類型為:String
			getUrl.setParameter(0, "127.0.0.1"); //按順序設定方法需要的參數值
			getUrl.setParameter(1, 10087);
			getUrl.setParameter(2, 123);
			getUrl.invoke(); //調用方法
			System.out.println(getUrl.getRetVal()); //輸出傳回值
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		
		try {
			JNative getPlayUrl = new JNative("EhfscliaxDll.dll", "getPlayUrl");
			getPlayUrl.setRetVal(Type.INT); //此方法在DLL中定義的傳回值類型為:const wchar_t*,如果設定傳回值類型為:String,則隻能擷取到傳回值的第一個字元
			
			String mgrIp = "127.0.0.1";
			Pointer ptr = Pointer.createPointerFromString(mgrIp);
			
			getPlayUrl.setParameter(0, ptr);
			getPlayUrl.setParameter(1, 10087);
			getPlayUrl.setParameter(2, 123);
			getPlayUrl.invoke();
			//個人了解getRetValAsInt是擷取傳回值的指針位址,getUnicodeMemoryAsString方法從指針位址的記憶體中讀取字元串
			String url = JNative.getUnicodeMemoryAsString(getPlayUrl.getRetValAsInt());
			System.out.println(url);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}
           

執行結果:

2014-5-25 22:48:46, [DEBUG] [org.xvolks.jnative.JNative] [loadLibrary]: Successfully loaded library 'EhfscliaxDll.dll', functionName = getUrl: hModule = 268435456
http://中文127.0.0.1:10087
2014-5-25 22:48:46, [DEBUG] [org.xvolks.jnative.pointers.memory.MemoryBlockFactory] [setPreferredMemoryType]: Using org.xvolks.jnative.pointers.memory.HeapMemoryBlock memory reservation strategy
http://-�17001:10087
2014-5-25 22:48:46, [DEBUG] [org.xvolks.jnative.JNative] [unLoad]: Unloading native library 'EhfscliaxDll.dll'
           

getUrl方法的傳回值類型為:const char*,結果是正常的,getPlayUrl的傳回值類型為:const wchar_t*,雖然通過getUnicodeMemoryAsString讀取到了傳回值,不是第一個字元,但中文亂碼的問題一直沒能解決。

本學習項目源碼下載下傳:http://download.csdn.net/detail/testcs_dn/7400203

你可能會遇到以下問題:

如何捕獲 System.loadLibrary 産生的異常?