`
logicigam
  • 浏览: 32948 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JNI参数传递以及中文编码问题解决

阅读更多
这两天因为需要做一个用java读写IC卡的程序,制卡厂商只提供的dll库,无奈之下只能去挖JNI了,期间遇到了两个大问题
1。中文字符乱码,按官方文档里的说法用JNI中的JNIEnv提供的GetStringUTFChars方法问题依旧。
废话不多说了,把解决方案贴出来,闹了半天就是字符位数的问题。
/*
   由jstring向char*的转换
*/

char* jstringTostring(JNIEnv* env, jstring jstr ) 
 { 
 int length = env->GetStringLength(jstr); 
 const jchar* jcstr = env->GetStringChars( jstr, 0 ); 
 char* rtn = (char*)malloc( length*2+1 ); 
 int size = 0; 
 size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn, 
 (length*2+1), NULL, NULL ); 
 if( size <= 0 ) 
 return NULL; 
 env->ReleaseStringChars( jstr, jcstr ); 
 rtn[size] = 0; 
 return rtn; 
 } 

/*
   由char*向jstring的转换
*/

jstring stringTojstring(JNIEnv* env,const char* s)   
  {   
  if (s == NULL)   
  return NULL;   
  int clen = lstrlen(s);   
  int wlen = clen+1;   
  WCHAR* cs = new WCHAR[wlen];   
  wlen = ::MultiByteToWideChar(CP_ACP,NULL,s,clen,cs,wlen);   
  cs[wlen]=NULL;   
  jstring js = env->NewString((const jchar*)(WCHAR*)cs,wlen);   
  delete[] cs;   
  return js;   
  }   

2。参数传递问题
我需要把通过调用dll返回的IC卡信息带到Java程序里来,返回值分散在多个变量里,没法直接通过一个函数返回值传回来,google了一整,例子全从java向C++方向传参的,最后在官方文档里找到解决方案:将返回值赋值给一个对象属性,将该对象作为函数的参数传进dll的方法中即可。方法如下:
/*
   obj需要赋值的对象
   fieldName属性名
   fieldType 属性签名(可通过在控制台javap -s [类全名]得到)
   value     属性值
*/

int setObjectField(JNIEnv* env,jobject obj,char *fieldName,char *fieldType,char *value){
  jfieldID fid;   /* store the field ID */
    jstring jstr;

    /* Get a reference to obj’s class */
    jclass cls = env->GetObjectClass(obj);
    /* Look for the instance field s in cls */
    fid = env->GetFieldID( cls, fieldName,
                             fieldType);
    if (fid == NULL) {
        return -1; /* failed to find the field */
    }

    /* Create a new string and overwrite the instance field */
	jstr=stringTojstring(env,value);
   
    if (jstr == NULL) {
        return -1; /* out of memory */
    }
    env->SetObjectField( obj, fid, jstr);
	return 0;
}
分享到:
评论

相关推荐

    jni数据传递demo

    例如,Java中的`int`在JNI中对应为`jint`,当调用Java方法时,我们可以将`jint`作为参数传递,反之亦然。 2. **数组传递**: JNI支持Java的一维和多维数组。对于一维数组,可以使用`GetIntArrayElements`或`...

    JNI学习二:字符串参数传递与返回值

    在本示例中,我们关注的是JNI中的字符串参数传递和返回值处理,这对于那些需要在Java和C/C++之间进行深度集成的项目非常重要。 1. **JNI基本概念** JNI是Java平台提供的一个接口,它使得开发者可以编写本地方法...

    jsp,java中文乱码问题另类解决方案,jni加密、解密编码

    然而,如果这些常规方法无法解决问题,我们可以尝试使用JNI来实现加密和解密。 JNI是Java平台提供的一种接口,允许Java代码调用本地(非Java)代码,如C/C++,以利用其性能优势或访问特定平台的功能。在处理中文...

    jni java传递对象到C

    1. **声明JNI函数**:在C/C++头文件中,我们需要声明一个JNI函数,该函数接受`JNIEnv`指针(提供访问Java虚拟机和Java对象的方法)以及`jobject`参数。 ```c JNIEXPORT void JNICALL Java_Package_Name_MethodName...

    使用JNI调用本地接口(解决中文问题)

    处理中文字符串的关键在于理解Unicode编码和JNI中的字符串转换。Java使用UTF-16编码存储字符串,这意味着每个字符占据16位。在C/C++中,我们可以使用`wchar_t`类型来处理宽字符,`GetStringChars`方法可以获取Java...

    JNI 调 C C++ 参数String

    在标题“JNI 调 C/C++ 参数String”中,我们将探讨如何通过JNI传递Java的String类型参数到C或C++函数,并在本地代码中进行处理。 首先,让我们了解JNI的基本结构。要使用JNI,你需要创建一个Java类,声明一些 ...

    jni相关文档以及代码

    3. **数据类型转换**:了解Java和C/C++之间的数据类型映射,如何在两者之间传递参数和返回值。 4. **异常处理**:学习如何在本地代码中捕获和抛出Java异常。 5. **内存管理**:理解JNI中如何分配和释放内存,避免...

    通过jni实现图像处理的demo

    至于支持汉字的传递和类的传递,这可能是指在JNI中处理包含汉字的字符串,以及将Java类的对象作为参数传递给本地方法。处理汉字需要确保编码正确,通常使用UTF-8编码。传递Java类的对象则需要使用JNI的NewGlobalRef...

    android jni 屏幕截图 NativeScreenCapture

    JNI包括一系列的函数调用,如`JNIEnv`指针,用于在Java和本地代码之间传递参数、调用Java方法等。 2. **屏幕截图原理**:Android系统的屏幕截图通常涉及获取显示服务器的缓冲区数据。在JNI中,我们需要通过系统服务...

    webrtc-android-jni

    5. **处理回调**:通过JNI接口,从C++层传递事件到Java层,如连接状态变化、音视频数据流等。 6. **音视频流处理**:实现音视频的采集、编码、传输、解码和渲染。这包括设置捕获设备、处理音频和视频帧,以及连接到...

    UVCCapture_jni.zip

    4. **预览显示**:转换后的JPEG或BMP图像数据可以通过JNI接口传递回Java层,然后在Android的SurfaceView或者TextureView上进行显示,实现预览功能。 5. **图片捕获**:当需要保存图片时,JNI代码会执行类似的转换...

    android jni jstring

    1. **获取`jstring`对象**:在JNI方法中,你可以通过参数接收Java层传递的`jstring`对象,或者通过`env-&gt;NewStringUTF()`等函数创建新的`jstring`。 2. **转换为C字符串**:使用`env-&gt;GetStringUTFChars()`函数,...

    jni 第1、2讲

    在这一讲中,我们还将讨论如何传递参数和返回值,以及处理异常。JNI提供了多种数据类型(如`jint`, `jdouble`, `jobject`等)来映射Java类型。此外,JNI的`JNIEnv`指针是一个关键组件,它包含了调用Java方法、访问...

    JNI线程使用.rar

    1. **线程创建**:展示如何在C/C++代码中创建和启动线程,以及如何传递参数到线程函数。 2. **同步原语**:使用pthread库中的互斥锁和条件变量来实现线程间的同步。 3. **JNI接口**:定义JNI函数,供Java层调用,...

    Android应用源码串口通信(JNI)例子.zip

    JNI接口定义了如何创建本地方法、如何在Java和本地代码之间传递参数以及如何处理异常。 2. **Android串口通信** 在Android中,由于安全限制,系统并未直接提供串口API。因此,通常需要使用JNI调用C/C++库来实现...

    jni.zip_jni_linux 红外

    标题中的“jni.zip_jni_linux 红外”暗示了这个压缩包可能包含了与JNI(Java Native...开发这样的系统涉及了JNI技术、Linux内核驱动编程、UART通信以及红外遥控协议的理解和实现,这些都是嵌入式系统开发中的关键技能。

    android JNI RSA 3DES BASE64 加解密实现

    4. **Java调用JNI**:在Java代码中加载本地库并调用已定义的JNI方法,将加密或解密的数据作为参数传递。 5. **测试和优化**:完成上述步骤后,进行单元测试确保加密解密功能正常工作。同时,根据性能需求进行优化,...

    jni资料整理

    本文将详细讲解JNI的相关知识点,包括其用途、基本概念、使用步骤、以及一些常见的问题和解决方案。 1. **JNI的基本概念**: - **本地方法(Native Method)**:Java中的方法如果声明为`native`,则表明该方法的...

    android jni使用字符串

    总结起来,Android中的JNI与`jstring`使用涉及到Java与C/C++之间的交互,包括如何获取和释放字符串的UTF-8表示,以及如何在两个环境中安全地传递数据。熟悉这些概念和操作对优化性能、利用原生库和实现特定功能至关...

    Jni开发之旅

    在Android系统中,JNI被广泛应用于性能敏感的模块,例如图像处理、音频视频编码解码,以及调用系统级API等。本示例"Jni开发之旅"将带你了解如何在Android应用中使用NDK进行JNI开发,实现Java代码调用C语言的接口函数...

Global site tag (gtag.js) - Google Analytics