最近安装eclipse给一个客户开发项目,项目中用jna调用了自定义的一个本地动态链接库,动态链接库名称是uuwisehelper.dll。该动态链接库的功能是验证码识别功能。
?
eclipse中调用调试是运行正常的,但是程序打包后报错提示加载动态库失败。
咨询优优云的技术(该动态链接库的技术支持)后获知DLL是C编写的。
?
于是在谷歌,百度,咨询优优云的动态链接库编译作者。得知C编写的动态链接库配合eclipse和jna的时候可能是C和Java的数据类型不一致,导致类型对应出现问题。
?
期间尝试了很多网上提供的方法。下面特此总结一下分享给大家:
?
1.将动态库路径写为绝对路径
?
2.同时也需要设置jna.library.path?在相应路径中加入动态链接库
?
3.JDK如果是64位的话,请更换一个32位的JDK重新调试打包一下。
?
一般做过以上三点之后,重新运行打包后的文件就不会提示加载加载动态库失败了。
?
特此分享在验证码识别时的样例代码如下:
?
?package?com.cqz.dm;
?
?
?import?java.awt.image.BufferedImage;
?import?java.io.ByteArrayOutputStream;
?import?java.io.File;
?import?java.io.FileInputStream;
?import?java.io.InputStream;
?
?import?javax.imageio.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?imageFile)?throws?Exception
{
BufferedImage?img?=?ImageIO.read(imageFile);
ByteArrayOutputStream?buf?=?new?ByteArrayOutputStream((int)?imageFile.length());
try
{
ImageIO.write(img,?"jpg",?buf);
}?catch?(Exception?e)
{
e.printStackTrace();
return?null;
}
return?buf.toByteArray();
}
?
public?static?byte[]?toByteArrayFromFile(String?imageFile)?throws?Exception
{
InputStream?is?=?null;
?
ByteArrayOutputStream?out?=?new?ByteArrayOutputStream();
?
try
{
is?=?new?FileInputStream(imageFile);
?
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:如有错误,望各位海涵。