`

JNI 数据类型转换、乱码解决方案

 
阅读更多
1:JNI 数据类型转换

下面是 Test.c

C代码收藏代码
  1. #include<jni.h>
  2. #include"com_test_Test.h"
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5. #include<strings.h>
  6. //获取字符串
  7. JNIEXPORTvoidJNICALLJava_com_test_Test_sayHello(JNIEnv*env,jobjectobj,
  8. jstrings){
  9. char*str=(char*)(*env)->GetStringUTFChars(env,s,0);
  10. printf("\nc-string:hello-%s",str);
  11. }
  12. //获取,返回int
  13. JNIEXPORTjintJNICALLJava_com_test_Test_add(JNIEnv*env,jobjectobj,
  14. jinta,jintb){
  15. inti=a;
  16. intj=b;
  17. printf("\nc-int:%d-%d",i,j);
  18. charstr[256];
  19. sprintf(str,"%d",i+j);
  20. return(jint)i+j;
  21. }
  22. //获取,返回float
  23. JNIEXPORTjfloatJNICALLJava_com_test_Test_getFloat(JNIEnv*env,jobjectobj,
  24. jfloatf){
  25. floatfl=f;
  26. printf("\nc-float:%3f",fl);
  27. fl=200.555;
  28. return(jfloat)fl;
  29. }
  30. //获取,返回double
  31. JNIEXPORTjdoubleJNICALLJava_com_test_Test_getDouble(JNIEnv*env,
  32. jobjectobj,jdoubledou){
  33. doubled=dou;
  34. printf("\nc-double:%3f",d);
  35. d=800.88;
  36. return(jdouble)d;
  37. }
  38. //获取,返回boolean
  39. JNIEXPORTjbooleanJNICALLJava_com_test_Test_getBoolean(JNIEnv*env,
  40. jobjectobj,jbooleanbool){
  41. unsignedcharb=bool;
  42. printf("\nc-boolean:%lu",b);
  43. if(b){
  44. printf("true");
  45. }else{
  46. printf("false");
  47. }
  48. b=1;
  49. return(jboolean)b;
  50. }
  51. //获取,返回string
  52. JNIEXPORTjstringJNICALLJava_com_test_Test_getString(JNIEnv*env,
  53. jobjectobj,jstrings){
  54. char*st=(char*)(*env)->GetStringUTFChars(env,s,0);
  55. printf("\nc-string:%s",st);
  56. char*str="hellowangwu!";
  57. jstringrtn;
  58. rtn=(*env)->NewStringUTF(env,str);
  59. returnrtn;
  60. }
  61. //获取,返回string[]
  62. JNIEXPORTjobjectArrayJNICALLJava_com_test_Test_getStringArray(JNIEnv*env,
  63. jobjectobj,jobjectArrayarr){
  64. intlen=(*env)->GetArrayLength(env,arr);
  65. printf("\nc-stringArray:");
  66. inti=0;
  67. for(i=0;i<len;i++){
  68. jobjectobj=(*env)->GetObjectArrayElement(env,arr,i);
  69. jstringstr=(jstring)obj;
  70. constchar*szStr=(*env)->GetStringUTFChars(env,str,0);
  71. printf("%d-%s",i,szStr);
  72. (*env)->ReleaseStringChars(env,str,szStr);
  73. }
  74. //-----返回----
  75. jstringstr;
  76. jobjectArrayargs=0;
  77. jsizesize=5;
  78. char*sa[]={"Hello,","world!","zhang","san","yuang"};
  79. intj=0;
  80. jclassobjClass=(*env)->FindClass(env,"java/lang/String");
  81. args=(*env)->NewObjectArray(env,size,objClass,0);
  82. for(j=0;j<size;j++){
  83. str=(*env)->NewStringUTF(env,sa[j]);
  84. (*env)->SetObjectArrayElement(env,args,j,str);
  85. }
  86. returnargs;
  87. }


下面是Test.java
Java代码收藏代码
  1. packagecom.test;
  2. publicclassTest{
  3. privatenativevoidsayHello(Stringstr);
  4. privatenativeintadd(inta,intb);
  5. privatenativefloatgetFloat(floatf);
  6. privatenativedoublegetDouble(doubled);
  7. privatenativebooleangetBoolean(booleanb);
  8. privatenativeStringgetString(Stringstr);
  9. privatenativeString[]getStringArray(String[]sa);
  10. static{
  11. System.loadLibrary("Test");
  12. }
  13. publicstaticvoidmain(String[]args){
  14. Testtest=newTest();
  15. test.sayHello("zhangsan");
  16. System.out.println("int-->"+test.add(10,20));
  17. System.out.println("float-->"+test.getFloat((float)20.123));
  18. System.out.println("double-->"+test.getDouble(100.369));
  19. System.out.println("boolean-->"+test.getBoolean(true));
  20. System.out.println("string-->"+test.getString("wangWu"));
  21. String[]ss={"hello","-","zhang","san"};
  22. Object[]obj=test.getStringArray(ss);
  23. System.out.print("string[]-->");
  24. for(Objectobject:obj){
  25. System.out.print(object+"");
  26. }
  27. }
  28. }



++++++++++++++++++++++++++++++++++++++++++++++++++
上面类型转换没有一个一个去试,应该都是可以的
++++++++++++++++++++++++++++++++++++++++++++++++++



2:JNI 乱码解决方案

顺便再转一个JNI相关的:jni乱码解决方案
http://www.wangchao.net.cn/bbsdetail_57022.html


Java代码:
Java代码收藏代码
  1. /*
  2. *javactransfer.java
  3. *Bydpwu
  4. *e-mail:dpwu_js@sina.com.cn
  5. */
  6. publicclassjavactransfer
  7. {
  8. publicStringhypotenuse(Stringsend_buf,Stringrecv_buf,interrno)
  9. {
  10. returnhypotenuse0(send_buf,recv_buf,errno);
  11. }
  12. privatenativeStringhypotenuse0(Stringsend_buf,Stringrecv_buf,interrno);
  13. static
  14. {
  15. System.loadLibrary("javactransfer");//调用dll
  16. }
  17. publicstaticvoidmain(String[]args)
  18. {
  19. javactransferobj=newjavactransfer();
  20. System.out.println("");
  21. System.out.println("");
  22. System.out.println("begin!");
  23. System.out.println("");
  24. System.out.println("");
  25. Stringjavasend="发送中文chinese!";
  26. System.out.println("javasend:"+"["+javasend+"]");
  27. Stringjavarecv=obj.hypotenuse("teststr",javasend,1);
  28. //javasend传含有中文字符串给C
  29. //javarecv接受C含有中的文字符串
  30. System.out.println("javarecv:"+"["+javarecv+"]");
  31. System.out.println("");
  32. System.out.println("");
  33. System.out.println("end!");
  34. }
  35. }


C实现代码为:

C代码收藏代码
  1. /*
  2.   *javactransfer.c
  3.   *Bydpwu
  4.   *e-mail:dpwu_js@sina.com.cn
  5.   */
  6.   #include<windows.h>
  7.   #include"javactransfer.h"//通过javah–jnijavactransfer生成
  8.   #include<stdio.h>
  9.   #include"stdlib.h"
  10.   #include"string.h"
  11.   char*jstringToWindows(JNIEnv*env,jstringjstr);
  12.   jstringWindowsTojstring(JNIEnv*env,char*str);
  13.   JNIEXPORTjstringJNICALL
  14.   Java_javactransfer_hypotenuse0(JNIEnv*env,jobjectobj,jstringsend_buf,jstringrecv_buf,jinterrno)
  15.   {
  16.   char*Buf_Return;
  17.   Buf_Return=(char*)malloc(1024);
  18.   
  19.   constchar*recvtest=jstringToWindows(env,recv_buf);
  20.   /*上句recvtest接收Java传过来的中文字符串正确,如果改为下句,则出现乱码:
  21.   constchar*recvtest=(*env)->GetStringUTFChars(env,recv_buf,0);
  22.   */
  23.   printf("crecv:[%s]\n",recvtest);
  24.   
  25.   sprintf(Buf_Return,"接收中文chinese!");
  26.   printf("\n\n\ncsend:[%s]\n",Buf_Return);
  27.   recv_buf=WindowsTojstring(env,Buf_Return);
  28.   /*上句recv_buf传windows本地C中含有中文字符串给Java正确;如果改为下句出现乱码:
  29.   recv_buf=(*env)->NewStringUTF(env,Buf_Return);
  30.   */
  31.   returnrecv_buf;
  32.   }
  33.   char*jstringToWindows(JNIEnv*env,jstringjstr)
  34.   {
  35.   intlength=(*env)->GetStringLength(env,jstr);
  36.   constjchar*jcstr=(*env)->GetStringChars(env,jstr,0);
  37.   char*rtn=(char*)malloc(length*2+1);
  38.   intsize=0;
  39.   size=WideCharToMultiByte(CP_ACP,0,(LPCWSTR)jcstr,length,rtn,(length*2+1),NULL,NULL);
  40.   if(size<=0)
  41.   returnNULL;
  42.   (*env)->ReleaseStringChars(env,jstr,jcstr);
  43.   rtn[size]=0;
  44.   returnrtn;
  45.   }
  46.   jstringWindowsTojstring(JNIEnv*env,char*str)
  47.   {
  48.   jstringrtn=0;
  49.   intslen=strlen(str);
  50.   unsignedshort*buffer=0;
  51.   if(slen==0)
  52.   rtn=(*env)->NewStringUTF(env,str);
  53.   else
  54.   {
  55.   intlength=MultiByteToWideChar(CP_ACP,0,(LPCSTR)str,slen,NULL,0);
  56.   buffer=malloc(length*2+1);
  57.   if(MultiByteToWideChar(CP_ACP,0,(LPCSTR)str,slen,(LPWSTR)buffer,length)>0)
  58.   rtn=(*env)->NewString(env,(jchar*)buffer,length);
  59.   }
  60.   if(buffer)
  61.   free(buffer);
  62.   returnrtn;
  63.   }



C++实现代码为:
C++代码收藏代码
  1. /*
  2. *javactransfer.cpp
  3. *Bydpwu
  4. *e-mail:dpwu_js@sina.com.cn
  5. */
  6. #include<windows.h>
  7. #include"javactransfer.h"//通过javah–jnijavactransfer生成
  8. #include<stdio.h>
  9. #include"stdlib.h"
  10. #include"string.h"
  11. char*jstringToWindows(JNIEnv*env,jstringjstr);
  12. jstringWindowsTojstring(JNIEnv*env,char*str);
  13. JNIEXPORTjstringJNICALL
  14. Java_javactransfer_hypotenuse0(JNIEnv*env,jobjectobj,jstringsend_buf,jstringrecv_buf,jint_tperrno)
  15. {
  16. char*Buf_Return;
  17. Buf_Return=(char*)malloc(1024);
  18. constchar*ctest=jstringToWindows(env,recv_buf);
  19. /*
  20. 如果把上句改为下句,C接收Java字符串时将出现乱码:
  21. constchar*ctest=(env)->GetStringUTFChars(recv_buf,0);
  22. */
  23. printf("crecv:[%s]\n",ctest);
  24. sprintf(Buf_Return,"接收中文chinese!");
  25. printf("\n\n\ncsend:[%s]\n",Buf_Return);
  26. recv_buf=WindowsTojstring(env,Buf_Return);
  27. /*上句执行正确,如果把上句换成下句,Java在接收C字符串时出现乱码
  28. recv_buf=(env)->NewStringUTF(Buf_Return);
  29. */
  30. returnrecv_buf;
  31. }
  32. char*jstringToWindows(JNIEnv*env,jstringjstr)
  33. {
  34. intlength=(env)->GetStringLength(jstr);
  35. constjchar*jcstr=(env)->GetStringChars(jstr,0);
  36. char*rtn=(char*)malloc(length*2+1);
  37. intsize=0;
  38. size=WideCharToMultiByte(CP_ACP,0,(LPCWSTR)jcstr,length,rtn,(length*2+1),NULL,NULL);
  39. if(size<=0)
  40. returnNULL;
  41. (env)->ReleaseStringChars(jstr,jcstr);
  42. rtn[size]=0;
  43. returnrtn;
  44. }
  45. jstringWindowsTojstring(JNIEnv*env,char*str)
  46. {
  47. jstringrtn=0;
  48. intslen=strlen(str);
  49. unsignedshort*buffer=0;
  50. if(slen==0)
  51. rtn=(env)->NewStringUTF(str);
  52. else
  53. {
  54. intlength=MultiByteToWideChar(CP_ACP,0,(LPCSTR)str,slen,NULL,0);
  55. buffer=(unsignedshort*)malloc(length*2+1);
  56. if(MultiByteToWideChar(CP_ACP,0,(LPCSTR)str,slen,(LPWSTR)buffer,length)>0)
  57. rtn=(env)->NewString((jchar*)buffer,length);
  58. }
  59. if(buffer)
  60. free(buffer);
  61. returnrtn;
  62. }
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics