`
provista
  • 浏览: 121826 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JNI的某些数组和字符串类型转换(转)

阅读更多
jbytearray转c++byte数组
jbyte * arrayBody = env->GetByteArrayElements(data,0); 
jsize theArrayLengthJ = env->GetArrayLength(data); 
BYTE * starter = (BYTE *)arrayBody; 


jbyteArray 转 c++中的BYTE[]
//jbytearray strIn
jbyte * olddata = (jbyte*)env->GetByteArrayElements(strIn, 0);
jsize  oldsize = env->GetArrayLength(strIn);
BYTE* bytearr = (BYTE*)olddata;
int len = (int)oldsize;


C++中的BYTE[]转jbyteArray
//nOutSize是BYTE数组的长度 BYTE pData[]
jbyte *by = (jbyte*)pData;
jbyteArray jarray = env->NewByteArray(nOutSize);
env->SetByteArrayRegin(jarray, 0, nOutSize, by);


jbyteArray 转 char *
char* data = (char*)env->GetByteArrayElements(strIn, 0);

char* 转jstring
jstring WindowsTojstring(JNIEnv* env, char* str_tmp)
{
 jstring rtn=0;
 int slen = (int)strlen(str_tmp);
 unsigned short* buffer=0;
 if(slen == 0)
 {
  rtn = env->NewStringUTF(str_tmp);
 }
 else
 {
  int length = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str_tmp, slen, NULL, 0);
  buffer = (unsigned short*)malloc(length*2+1);
  if(MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str_tmp, slen, (LPWSTR)buffer, length) > 0)
  {
   rtn = env->NewString((jchar*)buffer, length);
  }
 }
 if(buffer)
 {
  free(buffer);
 }
 return rtn;
}


下面这个没有用过,刚看到,也写进来,以后如果遇到可以验证下看。

jstring 转 char* 或者 const char*
// jstring str
const char *key = env->GetStringUTFChars(str, 0);
//jboolean isOffer
jsClient->modify(key, isOffer);
env->ReleaseStringUTFChars(str, key);


JNI 返回 jbyteArray
JNIEXPORT jbyteArray JNICALL Java_Test_getByteArray(JNIEnv *env, jobject obj)
{
    jbyteArray firstMacArray = env->NewByteArray( 6 );
    ......
    jbyte *bytes = env->GetByteArrayElements( firstMacArray, 0);
    for ( int i = 0; i < sizeof( pAdapterInfo->Address ); i++ )
    {
       bytes[ i ] = pAdapterInfo->Address[ i ];
    }

    env->SetByteArrayRegion(firstMacArray, 0, 6, bytes );
    return firstMacArray;
}


//jstring to char*
char* jstringTostring(JNIEnv* env, jstring jstr)
{        
  char* rtn = NULL;
  jclass clsstring = env->FindClass("java/lang/String");
  jstring strencode = env->NewStringUTF("utf-8");
  jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
  jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
  jsize alen = env->GetArrayLength(barr);
  jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
  if (alen > 0)
  {
    rtn = (char*)malloc(alen + 1);
    memcpy(rtn, ba, alen);
    rtn[alen] = 0;
  }
  env->ReleaseByteArrayElements(barr, ba, 0);
  return rtn;
}


//char* to jstring
jstring stoJstring(JNIEnv* env, const char* pat)
{
jclass strClass = env->FindClass("Ljava/lang/String;");
jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
jbyteArray bytes = env->NewByteArray(strlen(pat));
env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
jstring encoding = env->NewStringUTF("utf-8");
return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
} 


//将jstring类型转换成windows类型
char* jstringToWindows( 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;
}

//将windows类型转换成jstring类型
jstring WindowsTojstring( 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;
}
/*JNIEXPORT jstring JNICALL Java_test_cs_web_SWIFTAlianceCASmfTest_strcal
(JNIEnv *env, jclass obj, jstring jstr1, jstring jstr2)
{
jbyteArray bytes = 0;
jthrowable exc;
char *pszResult = NULL;    
char *pszSTR1 = NULL;
char *pszSTR2 = NULL;

pszSTR1 = jstringTostring(env, jstr1);
pszSTR2 = jstringTostring(env, jstr2);


int nlen = sizeof(char)*(strlen(pszSTR1)+strlen(pszSTR2));
pszResult = (char*)malloc(nlen);
strcpy(pszResult, pszSTR1);
strcat(pszResult, pszSTR2);

jstring jstrRe = stoJstring(env, pszResult);
free(pszSTR1);
free(pszSTR2);
free(pszResult);
return(jstrRe);
}
*/



jni object的使用

每一个jni格式的dll中的object对应该java里面的一个类。
如下例有一个 ObjData类,类中有成员bData ,Len
public class ObjData {
  public byte[]  bData;
  public int Len;       
}
//------------------------jni获得传过来的Object类型的变量objDataIn--------

jclass clazz =(env)->FindClass("ObjData");

//从传进来的对象中取出byte[]
jfieldID byteData = (env)->GetFieldID(clazz,"bData","[B");
jbyteArray pDataIn = (jbyteArray) (env)->GetObjectField(objDataIn, byteData);
jsize theArrayLeng = env->GetArrayLength(pDataIn);

//byte[]转为BYTE[]
jbyte * arrayBody = env->GetByteArrayElements(pDataIn,0); 
BYTE * jDataIn = (BYTE *)arrayBody; 



//将BYTE数组转为jarray
jbyte* byte = (jbyte*)jDataOut;    
jbyteArray jarray = env->NewByteArray(theArrayLeng);
env->SetByteArrayRegion(jarray, 0, theArrayLeng, byte);


//给每一个实例的变量付值
(env)->SetObjectField(objDataIn,byteData,jarray);
(env)->SetIntField(objDataIn,pDataInLen,jDataInLen);
(env)->ReleaseByteArrayElements(pDataIn, arrayBody, 0); 


其他参考:
Java 通过JNI调用C或者CPP代码
http://blog.csdn.net/kenera/archive/2009/02/16/3895343.aspx
http://apps.hi.baidu.com/share/detail/15732549
http://dniit.blog.163.com/blog/static/28012894200842810332491/
http://hi.baidu.com/liangwind/blog/item/7dcce2c9729d1d1e7f3e6f49.html
分享到:
评论
2 楼 hnraysir 2015-04-20  
谢谢你的分享!对我有帮助!
1 楼 yejiurui 2013-03-20  
楼主 你这篇文章简直是太好了,多谢啊

相关推荐

    jni传递对象数组

    对象数组的处理涉及到对Java虚拟机(JVM)的内存管理和类型转换的理解。 1. **创建本地方法** 在Java类中,我们可以声明一个本地方法,使用`native`关键字,例如: ```java public class JniObjArrayExample { ...

    jni数据类型转换

    java向native传递常用基本数据类型 和字符串类型 2. java向native传递数组类型 3. java向native传递自定义java对象 4. java向native传递任意java对象(以向native传递ArrayList为例) 5. native向java传递数组...

    Android Studio 数组传递 JNI 示例程序

    【Android Studio 数组传递 JNI 示例程序】 在Android开发中,JNI(Java Native Interface)...注意,使用JNI需要注意内存管理,避免内存泄漏和错误的类型转换。在实际项目中,可能还需要处理多线程、异常处理等问题。

    JNI文档资料源码_2020_01_28_2.zip

    【Android NDK 开发】JNI 方法解析 ( 字符串数组参数传递 | 字符串遍历 | 类型强转 | Java 字符串与 C 字符串转换 | 字符串释放 ) 博客地址 : https://hanshuliang.blog.csdn.net/article/details/104103097 I...

    free pascal (lazarus) 版的 android NDK (JNI)调用范例、数据类型转换示例

    在Free Pascal中,可以使用`JNIEnv`指针的`GetStringUTFChars()`和`ReleaseStringUTFChars()`方法获取和释放字符串的UTF-8表示。 - **数值类型**:例如,Java的`int`在C/C++中为`jint`,`double`为`jdouble`。Free ...

    jni 构造字符串

    总的来说,JNI中的字符串操作需要对Java和C/C++的内存管理、异常处理以及Unicode编码有深入理解。通过`NewString`,开发者可以在C/C++代码中创建Java字符串对象,进而实现更灵活的跨语言交互。在实际开发中,应确保...

    java与c交互传递字符串和整型

    3. **字符串数组传递**:与单个字符串类似,字符串数组也需要转换为C的字符指针数组。`NewObjectArray`用于创建一个新的对象数组,`GetObjectArrayElement`获取数组中的元素,然后将每个元素转换为C字符串。处理完毕...

    DELPHI开发JNI必备 jni.pas

    6. **字符串和转换**:JNI提供了将Java字符串转换为本地字符串,以及反之的转换函数,方便数据交换。 在实际开发中,Delphi程序员需要理解JNI的生命周期管理,比如如何正确地创建和释放本地引用,以防止Java对象...

    JNI CHM文档以及JNI编程规范

    8. **字符串处理**:JNI提供了Java字符串和本地字符串之间的转换,以及字符串操作的功能。 9. **文件I/O**:虽然Java本身提供了丰富的I/O接口,但有时本地代码可能需要直接操作文件系统,JNI为此提供了支持。 通过...

    JNI 完全技术手册

    -JNI的使用涉及数据类型的对应关系,包括Java基本数据类型和引用类型(如String、对象、数组)与C/C++类型的转换和传递方法。 - 处理JNI中的字符串、整型数组、字符串数组和对象数组等数据的传递和处理。 - Java程序...

    Android的jni的应用C,C++(基本类型,数组,类(结构体))-文档

    Android的JNI(Java Native Interface)允许开发者在Android应用程序中使用C和C++代码,这在处理性能敏感或需要利用...通过理解基本类型、数组和类(结构体)的转换和处理方式,你可以在Android应用中灵活地运用JNI。

    JNI技术手册

    10. **字符串处理**:JNI提供了处理Java字符串到C字符串的转换函数,如GetStringUTFChars和ReleaseStringUTFChars。 11. **数组操作**:JNI支持对Java数组的访问,包括基本类型数组和对象数组,提供了...

    androidjni编程,java和c层的互相通信传递数据

    - `字符串处理`:Java的`String`在JNI中表示为`jstring`,可以使用`GetStringUTFChars()`获取其UTF-8编码的字符数组。 4. **性能考虑** - 跨语言调用开销:虽然JNI提供了高效的本地代码执行,但Java到C/C++的调用...

    JNI中文手册

    7. **字符串和字符集**:JNI处理Java字符串和本地字符串的转换,涉及到Unicode编码和本地字符集的转换问题。 8. **动态链接库**:如何在Java中加载和使用动态链接库(DLL或.so文件),以及如何在本地代码中调用Java...

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

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

    JNI-Java Native Interface资料(精华)

    通过JNI,开发人员可以创建、检查和更新Java对象(包括数组和字符串),调用Java方法,捕获和抛出异常,加载类并获取类信息,执行运行时类型检查。然而,使用JNI也意味着放弃了Java提供的某些好处,比如自动内存管理...

    JNI类型传递

    频繁的类型转换和跨语言调用可能导致性能下降,因此,合理设计接口并尽量减少转换次数是提高效率的关键。 总结来说,JNI类型的传递涉及到Java和本地代码之间的复杂交互,特别是处理结构体和类对象时。理解JNI的类型...

    jni.h文件,完美适配ida软件,直接就可以使用。

    7. **字符串和字符数组**:JNI提供了处理Java字符串和字符数组的方法,如`NewStringUTF`、`GetStringUTFChars`和`ReleaseStringUTFChars`。 通过使用`jni.h`与IDA的结合,开发者能够深入理解Java应用的本地代码逻辑...

    JNI完全技术手册 带完整书签

    15.2.2.5 传递字符串数组... 30 15.2.2.6 传递对象数组... 31 Chap7:Jni中C++和Java的参数传递... 33 Chap8:如何将java传递过来的jbyteArray转换成C/C++中的BYTE数组... 47 Chap5:使用JNI技术实现java程序调用第...

Global site tag (gtag.js) - Google Analytics