最近安裝eclipse給一個客戶開發項目,項目中用jna調用了自定義的一個本地動態連接庫,動態連接庫名稱是uuwisehelper.dll。該動態連接庫的功能是驗證碼識別功能。java
eclipse中調用調試是運行正常的,可是程序打包後報錯提示加載動態庫失敗。eclipse
諮詢優優雲的技術(該動態連接庫的技術支持)後獲知DLL是C編寫的。ide
因而在谷歌,百度,諮詢優優雲的動態連接庫編譯做者。得知C編寫的動態連接庫配合eclipse和jna的時候多是C和Java的數據類型不一致,致使類型對應出現問題。函數
期間嘗試了不少網上提供的方法。下面特此總結一下分享給你們:測試
1.將動態庫路徑寫爲絕對路徑this
2.同時也須要設置jna.library.path 在相應路徑中加入動態連接庫spa
3.JDK若是是64位的話,請更換一個32位的JDK從新調試打包一下。調試
通常作過以上三點以後,從新運行打包後的文件就不會提示加載加載動態庫失敗了。code
特此分享在驗證碼識別時的樣例代碼以下:ip
package com.cqz.dm;
import java.awt.p_w_picpath.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import javax.p_w_picpathio.ImageIO;
import com.sun.jna.Library;
import com.sun.jna.Native;
/**
* 更多函數細節:dll.uuwise.com
*
*/
public class CQZDMDLL
{
public static String USERNAME = "UserName"; //UU用戶名
public static String PASSWORD = "PassWord"; //UU密碼
public static String DLLPATH = "lib\\UUWiseHelper"; //DLL
public static String IMGPATH = "img\\test.png";
public static int SOFTID = 2097; //軟件ID
public static String SOFTKEY = "b7ee76f547e34516bc30f6eb6c67c7db"; //軟件KEY
public interface DM extends Library
{
DM INSTANCE = (DM) Native.loadLibrary(DLLPATH, DM.class);
public int uu_reportError(int id);
public int uu_setTimeOut(int nTimeOut);
public void uu_setSoftInfoA(int softId, String softKey);
public int uu_loginA(String UserName, String passWord);
public int uu_getScoreA (String UserName, String passWord);
public int uu_recognizeByCodeTypeAndBytesA (byte[] picContent, int piclen, int codeType, byte[] returnResult);
public void uu_getResultA(int nCodeID,String pCodeResult);
}
public static void main(String[] args) throws Exception
{
int userID;
DM.INSTANCE.uu_setSoftInfoA(SOFTID, SOFTKEY);
userID=DM.INSTANCE.uu_loginA(USERNAME, PASSWORD);
if(userID>0){
System.out.println("userID is:"+userID);
System.out.println("user score is:"+DM.INSTANCE.uu_getScoreA(USERNAME, PASSWORD));
File f = new File(IMGPATH);
byte[] by = toByteArray(f);
byte[] resultBtye=new byte[30]; //爲識別結果申請內存空間
int codeID=DM.INSTANCE.uu_recognizeByCodeTypeAndBytesA(by, by.length, 1, resultBtye); //調用識別函數,resultBtye爲識別結果
String resultResult = new String(resultBtye,"UTF-8");
resultResult=resultResult.trim();
System.out.println("this img codeID:"+codeID);
System.out.println("return recongize Result:"+resultResult);
/*
//測試報錯 開始,真實環境不可這樣用,須要在實際驗證碼打錯的狀況下,執行報錯函數進行報錯,惡意報錯會致使封號
System.out.println("報錯前 user score is:"+DM.INSTANCE.uu_getScoreA(USERNAME, PASSWORD));
int reportErrorResult;
reportErrorResult=DM.INSTANCE.uu_reportError(codeID);
if(reportErrorResult==0)
{
System.out.println("報錯後 user score is:"+DM.INSTANCE.uu_getScoreA(USERNAME, PASSWORD));
}else
{
System.out.println("報錯失敗,緣由未知");
}
//測試報錯 開始,真實環境不可這樣用,須要在實際驗證碼打錯的狀況下,執行報錯函數進行報錯,惡意報錯會致使封號
*/
}else{
System.out.println("登陸失敗,錯誤代碼爲:"+userID); //錯誤代碼請對應dll.uuwise.com各函數值查看
}
}
public static byte[] toByteArray(File p_w_picpathFile) throws Exception
{
BufferedImage img = ImageIO.read(p_w_picpathFile);
ByteArrayOutputStream buf = new ByteArrayOutputStream((int) p_w_picpathFile.length());
try
{
ImageIO.write(img, "jpg", buf);
} catch (Exception e)
{
e.printStackTrace();
return null;
}
return buf.toByteArray();
}
public static byte[] toByteArrayFromFile(String p_w_picpathFile) throws Exception
{
InputStream is = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
try
{
is = new FileInputStream(p_w_picpathFile);
byte[] b = new byte[1024];
int n;
while ((n = is.read(b)) != -1)
{
out.write(b, 0, n);
}// end while
} catch (Exception e)
{
throw new Exception("System error,SendTimingMms.getBytesFromFile", e);
} finally
{
if (is != null)
{
try
{
is.close();
} catch (Exception e)
{}// end try
}// end if
}// end try
return out.toByteArray();
}
}
PS:若有錯誤,望各位海涵。