JNI调用第三方C++ dll_C/C++_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > C/C++ > JNI调用第三方C++ dll

JNI调用第三方C++ dll

 2014/6/16 16:08:41  mjm13  程序员俱乐部  我要评论(0)
  • 摘要:最近工作需要要调用第三方厂商提供的dll,学了下JNI,来分享下。说明:使用JNI来调用dll是JAVA调用符合JNI规范的dll,如需调用第三方的dll是在符合JNI规范的dll中再用c++掉用第三方的dll中的方法。操作步骤:1.新建java类将需要掉用的方法声明为native,增加导入dll的代码,例如:publicstaticnativeArrayListreadCard(byte[]dataBuf);static{System.loadLibrary("XFBankJni");
  • 标签:c++

? ? ?最近工作需要要调用第三方厂商提供的dll,学了下JNI,来分享下。

?

? ? ?说明:使用JNI来调用dll是JAVA调用符合JNI规范的dll,如需调用第三方的dll是在符合JNI规范的dll中再用c++掉用第三方的dll中的方法。

?

? ? 操作步骤:

? ? 1.新建java类将需要掉用的方法声明为native,增加导入dll的代码,例如:
? ??

class="java" name="code">	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++所以碰到很多很低级的问题,写在这里希望对跟我一样不博学的人有帮助 ^_^)

  1. ? ??将java生成的“xxx.h”头文件拷贝到vs2010中保存之后各种报错,无法解析JNIEXPORT等JNI关键字
    解决方法:VS中在项目上右键打开属性 -> C/C++ -> 常规-> 附加包含目录: 添加jni对应的头文件
  2. VS报错找未定义标识符 malloc,_T()
    解决方法:增加导入#include "malloc.h",#include "tchar.h"
  3. VS中自己新增的本地方法也报 未定义标识符 “函数名”
    解决方法:将自己写的工具方法增加到文件的include下方,
  4. C++中设置的char数组接收后显示错误
    解决方法:增加分配内存的方法memset(char数组, 0, sizeof(char数组));
  5. ?在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));
  6. 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);
    ?
  7. 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对象工具方法:

https://database.cs.brown.edu/svn/hstore/branches/newdtxn-branch/third_party/cpp/tpceloader/drivers/JNIUtils.cpp

  • 大小: 116.2 KB
  • 查看图片附件
发表评论
用户名: 匿名