最近工作需要要调用第三方厂商提供的dll,学了下JNI,来分享下。
说明:使用JNI来调用dll是JAVA调用符合JNI规范的dll,如需调用第三方的dll是在符合JNI规范的dll中再用c++掉用第三方的dll中的方法。
操作步骤:
1.新建java类将需要掉用的方法声明为native,增加导入dll的代码,例如:
public static native ArrayList readCard(byte[] dataBuf); static { System.loadLibrary("XFBankJni"); }
其中load的部分不是固定的,C++的项目生成的dll文件名即可
2.先使用javac命令编译java类,然后使用javah命令编译 会生成“包名_java类名.h”,“.h”为C++中dll的头文件
3.vs新建一个C++的Win32项目,应用程序类型选择DLL,将生成的头文件拷贝带该项目中。
4.在生成的项目名.CPP文件中导入该头文件,并实现这些方法。
5.调用第三方dll,申明方法,加载dll
HINSTANCE hDLL = LoadLibrary(_T("XfBankRwCard.dll"));//加载dll if(hDLL==NULL){ return jobjct(); } typedef int (WINAPI *InnoverCard)(char* dataBuf);//申明第三方dll中方法格式 InnoverCard icard=(InnoverCard)GetProcAddress(hDLL,"innoverCard");//加载dll中的方法 int result = icard(data);//调用第三方方法
碰到的问题:(由于没用过vs,c++所以碰到很多很低级的问题,写在这里希望对跟我一样不博学的人有帮助 ^_^)
- 将java生成的“xxx.h”头文件拷贝到vs2010中保存之后各种报错,无法解析JNIEXPORT等JNI关键字。
解决方法:VS中在项目上右键打开属性 -> C/C++ -> 常规-> 附加包含目录: 添加jni对应的头文件
- VS报错找未定义标识符 malloc,_T()
解决方法:增加导入#include "malloc.h",#include "tchar.h" - VS中自己新增的本地方法也报 未定义标识符 “函数名”
解决方法:将自己写的工具方法增加到文件的include下方, - C++中设置的char数组接收后显示错误
解决方法:增加分配内存的方法memset(char数组, 0, sizeof(char数组)); - 在JNI中返回List对象,C++中的对象不能直接塞到list中需要转换为java对象 java才能接收否则会为null
jclass cls_ArrayList = env->FindClass("java/util/ArrayList"); jmethodID construct = env->GetMethodID(cls_ArrayList,"<init>","()V"); jobject obj_ArrayList = env->NewObject(cls_ArrayList,construct,""); jmethodID arrayList_add = env->GetMethodID(cls_ArrayList,"add","(Ljava/lang/Object;)Z"); env->CallObjectMethod(obj_ArrayList,arrayList_add,makeInteger(env,result)); env->CallObjectMethod(obj_ArrayList,arrayList_add,makeDouble(env,test));
- C++中inout参数的调用写法
char* databufChar = (char*)env->GetByteArrayElements(databuf, 0); double cardgases = 0; char cardno[11]; memset(cardno, 0, sizeof(cardno)); int result = readCard(databufChar,(char*)cardno,&cardgases);
- JNI char*转String工具方法
jstring stoJstring(JNIEnv *env, char* str){ jstring rtn = 0; int slen = strlen(str); unsigned short * buffer = 0; if( slen == 0 ) rtn = (env)->NewStringUTF(str ); else { int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 ); buffer = (unsigned short *)malloc( length*2 + 1 ); if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length )>0 ) rtn = (env)->NewString( (jchar*)buffer, length ); } if( buffer ) free( buffer ); return rtn; }
参考资料:
http://www.cnblogs.com/AnnieKim/archive/2012/01/01/2309567.html
http://blog.csdn.net/u_xtian/article/details/6033963
网上找的jni基础类型转java对象工具方法:
相关推荐
该实例是我自己写的jni调用第三方dll例子,可以作为参考,运行环境vs2010,其他环境没试过。
java用jni调用第三方C++写的dll,java接收C++结构体
jni调用c++ delphi中的dll.
完整的实现java跨平台调用C程序源码,包含JAVA源码和C源码以及编译后的demo dll。将dll放到jdk bin目录下,java 项目可以直接运行。若要修改dll可以,修改C源码后重新编译生成dll。该demo处理了多线程调用c,全局...
JAVA如何调用dll:用JNI调用C或C++动态联接库原来如此简单
java 调用 dll 的方法,即JNI的使用,demo中有get()/set()方法,操作步骤详细,即使是没用过java的程序员按照步骤依然可以成功。
Java通过JNI调用C++接口,Demo文档描述(里面有代码),里面有Windows下调用版和linux下调用版,经本人亲自测试,可用。
完整的展示了Java调用C++ API/dll示例程序. 说明如下: 1. mrSocketAPICInt是准备被java调用的API 2. mrSocketAPIJavaInt是java调用C++ api的中间层 3. mrSocketAPIJavaIntDemo是java程序,展示与C++ api如何对接。...
springboot+jna/jni调用动态so/dll库
通过jni完成java调用c/c++,包含c/c++生成Dll动态库
请C++同事帮忙写个dll程序,dll去解析开发平台输出的二进制流数据,上层应用平台调用dll得到json报文,然后再去做一些业务处理。 那现在上层应用面临的问题:访问java外部功能接口实现方式(即调用dll)怎么选择及...
利用JNI技术实现Java中调用C++编写的函数库示例程序源码,并附上参考JNI文档。...详情见本人博客:Java学习之通过JNI调用C/C++编写的dll链接库(图文教程)(http://write.blog.csdn.net/postlist)
里面是一个java使用JNI调用的实例,包含所有情况如结构体、指针等等
JAVA如何调用dll:用JNI调用C或C++动态联接库原来如此简单
visual studio 2019下C++通过JNI调用JAVA代码,实现一个简单的打印输出!!!
本资源包括JAVA工程,C++工程,C#dll测试工程
Java通过JNI调用Eclipse、MinGW编译C++出来的dll,仅仅是一个简单的示例,关键是整个流程要走通,详细参见:http://blog.csdn.net/yanzi1225627/article/details/18891613
NULL 博文链接:https://wuneng94zui.iteye.com/blog/1218725
该Demo有两个主要的例子,一个实现的是在java程序中调用DLL中的方法;而一个则是讲述如何在C++代码中调用Java类中的方法、详细阐述了JNI机制的使用,是一个很好的学习例子。
JAVA如何调用dll:用JNI调用C或C++动态联接库原来如此简单.doc