呆羊在曬太陽  
          公告
          • Y:哦,是你呀。
            X:我現(xiàn)在正在忙。
            Y:忙什么?
            X:呵呵,今天出太陽了,我把錢搬出來曬一曬。
            ***********************
            abc
            小叉
            很高興能結(jié)識(shí)大家!
            ***********************
          日歷
          <2005年12月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567
          統(tǒng)計(jì)
          • 隨筆 - 164
          • 文章 - 2
          • 評(píng)論 - 196
          • 引用 - 0

          導(dǎo)航

          常用鏈接

          留言簿(7)

          隨筆分類(158)

          文章分類(2)

          相冊(cè)

          log

          搜索

          •  

          積分與排名

          • 積分 - 71012
          • 排名 - 779

          最新評(píng)論

          閱讀排行榜

           

          JavaC之間通過JNI傳遞中文字符串

          簡(jiǎn)介 

          本文提供一個(gè)具體的實(shí)例,說明JavaC之間通過JNI傳遞含有中文字符串的參數(shù),解決中文亂碼問題(雙字節(jié)或多字節(jié)亂碼)。本文給出具體的源代碼,對(duì)源代碼進(jìn)行了解釋,C部分提供了 CC++兩種方式實(shí)現(xiàn)的完整代碼。并且所有代碼均在實(shí)驗(yàn)環(huán)境下測(cè)試通過。本文讀者須對(duì)JavaC(C++)有一定的基礎(chǔ)知識(shí)。

          實(shí)驗(yàn)環(huán)境

          Windows XP (或Windows2000

          j2sdk1.4.2/j2re1.4.2

          Microsoft VisualC++6.0

          安裝好j2sdk后需要設(shè)置環(huán)境變量

          CLASSPATH=.;C:\j2sdk1.4.2\bin;C:\j2sdk1.4.2\lib\dt.jar;C:\j2sdk1.4.2\lib\tools.jar;C:\j2sdk1.4.2\lib\htmlconverter.jarj2sdk安裝在c:\j2sdk1.4.2目錄下)

          源代碼及代碼說明

          Java代碼:

          /*

           * javactransfer.java

           * By dpwu

           * e-maildpwu_js@sina.com.cn

           */

          public class javactransfer

          {

            public String hypotenuse(String send_buf,String recv_buf,int errno)

            {

              return hypotenuse0(send_buf,recv_buf,errno);

            }

           

            private native String  hypotenuse0(String send_buf,String recv_buf,int errno);

           

            static

            {

              System.loadLibrary("javactransfer");//調(diào)用dll

            }

            public static void main( String[] args )

            {

           

               javactransfer obj= new javactransfer();

               System.out.println("");

               System.out.println("");

               System.out.println("       begin!");

               System.out.println("");

               System.out.println("");

               String javasend="發(fā)送中文chinese!";

               System.out.println(" java send:"+"["+javasend+"]");

          String javarecv=obj.hypotenuse("teststr",javasend,1); 

          //javasend傳含有中文字符串給C

          //javarecv接受C含有中的文字符串

               System.out.println(" java recv:"+"["+javarecv+"]");

               System.out.println("");

               System.out.println("");

               System.out.println("        end!");

             }

          }

           

           

           

          C實(shí)現(xiàn)代碼為:

          /*

           * javactransfer.c

           * By dpwu

           * e-maildpwu_js@sina.com.cn

           */

           

          #include <windows.h>

          #include "javactransfer.h"http://通過javah –jni javactransfer 生成

          #include <stdio.h>

          #include "stdlib.h"

          #include "string.h"

           

          char* jstringToWindows( JNIEnv *env, jstring jstr );

          jstring WindowsTojstring( JNIEnv* env, char* str );

           

          JNIEXPORT jstring JNICALL

          Java_javactransfer_hypotenuse0(JNIEnv *env,jobject obj,jstring send_buf,jstring recv_buf,jint errno)

          {

            char * Buf_Return;

           

            Buf_Return  =  (char*)malloc(1024);

           

            const char * recvtest = jstringToWindows( env, recv_buf );

          /*上句recvtest接收Java傳過來的中文字符串正確,如果改為下句,則出現(xiàn)亂碼:

          const char * recvtest = (*env)->GetStringUTFChars( env,recv_buf,0); 

          */

          printf( " c  recv  :[%s]\n" , recvtest);

           

            sprintf(Buf_Return,"接收中文chinese!");

            printf( "\n\n\n c send   :[%s]\n" , Buf_Return);

            recv_buf = WindowsTojstring(env ,Buf_Return);

          /*上句recv_bufwindows本地C中含有中文字符串給Java正確;如果改為下句出現(xiàn)亂碼:

          recv_buf = (*env)->NewStringUTF( env, Buf_Return );

            */

            return recv_buf;

          }

          char* jstringToWindows( JNIEnv  *env, jstring jstr )

          {

            int length = (*env)->GetStringLength(env,jstr );

            const jchar* jcstr = (*env)->GetStringChars(env,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(env,jstr, jcstr );

            rtn[size] = 0;

            return rtn;

          }

           

          jstring WindowsTojstring( JNIEnv* env, char* str )

          {

            jstring rtn = 0;

            int slen = strlen(str);

            unsigned short* buffer = 0;

            if( slen == 0 )

              rtn = (*env)->NewStringUTF(env,str );

            else

            {

              int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );

              buffer = malloc( length*2 + 1 );

              if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )

                rtn = (*env)->NewString( env, (jchar*)buffer, length );

            }

            if( buffer )

            free( buffer );

            return rtn;

          }

          javactransfer.java,javactransfer.c均放在d:\javac目錄下


          javac javactransfer.java :
          編譯java源代碼;

          javah –jni javactransfer :生成頭文件;

          cl -Ic:\j2sdk1.4.2\include -Ic:\j2sdk1.4.2\include\win32  -LD javactransfer.c -Fejavactransfer.dll

          通過Microsoft Visual C++C源代碼生成dll文件,供java調(diào)用。

          執(zhí)行結(jié)果如下:

           

          C++實(shí)現(xiàn)代碼為:

          /*

           * javactransfer.cpp

           * By dpwu

           * e-maildpwu_js@sina.com.cn

           */

           

          #include <windows.h>

          #include "javactransfer.h"http://通過javah –jni javactransfer 生成

          #include <stdio.h>

          #include "stdlib.h"

          #include "string.h"

           

          char* jstringToWindows( JNIEnv *env, jstring jstr );

          jstring WindowsTojstring( JNIEnv* env, char* str );

           

          JNIEXPORT jstring JNICALL

          Java_javactransfer_hypotenuse0(JNIEnv *env,jobject obj,jstring send_buf,jstring recv_buf,jint _tperrno)

           

          {

            char * Buf_Return;

            Buf_Return  =  (char*)malloc(1024);

           

            const char * ctest = jstringToWindows( env, recv_buf );

          /*

            如果把上句改為下句,C接收Java字符串時(shí)將出現(xiàn)亂碼:

            const char *ctest = (env)->GetStringUTFChars(  recv_buf , 0);

          */

            printf( " c  recv  :[%s]\n" , ctest);

           

            sprintf(Buf_Return,"接收中文chinese!");

            printf( "\n\n\n c send   :[%s]\n" , Buf_Return);

            recv_buf = WindowsTojstring(env ,Buf_Return);

          /*上句執(zhí)行正確,如果把上句換成下句,Java在接收C字符串時(shí)出現(xiàn)亂碼

          recv_buf = (env)->NewStringUTF(Buf_Return);

          */

            return recv_buf;

          }

          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;

          }

           

          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;

          }

          當(dāng)為C++實(shí)現(xiàn)時(shí),只需要在編譯時(shí)改為

          cl -Ic:\j2sdk1.4.2\include -Ic:\j2sdk1.4.2\include\win32 -LD javactransfer.cpp -Fejavactransfer.dll

           

          后話

          本文所述內(nèi)容可以應(yīng)用于復(fù)雜系統(tǒng)的改造,現(xiàn)有大型生產(chǎn)系統(tǒng)(例如:金融等)很多都是unix+C+tuxedo基于共享內(nèi)存實(shí)現(xiàn),而這些系統(tǒng)為了滿足安全和響應(yīng)時(shí)間要求不可能在短期內(nèi)完全丟棄,本文中提供的方法,可以和tuxedo客戶端通過VC++封裝成各種dll,這些dll可以在tuxedo本身很多優(yōu)良特性的基礎(chǔ)上進(jìn)行基于Java的開發(fā),以用來解決新的基于WEB應(yīng)用的需求。如有錯(cuò)誤之處,請(qǐng)與筆者聯(lián)系:dpwu_js@sina.com.cn

           

          參考資料:David Wendt NLS strings and JNI

           WebSphere programmer, IBM

          posted on 2005-12-08 10:31 小叉 閱讀(1413) 評(píng)論(3)  編輯  收藏 所屬分類: 轉(zhuǎn)載
          評(píng)論:
           
          Copyright © 小叉 Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 灌云县| 乌海市| 内乡县| 鲁山县| 平乐县| 东乡族自治县| 临西县| 西华县| 盐源县| 周宁县| 来宾市| 郸城县| 黄山市| 大悟县| 邵武市| 常熟市| 噶尔县| 庆安县| 尼勒克县| 南雄市| 榆树市| 若尔盖县| 静乐县| 武宁县| 澄城县| 巴楚县| 长宁区| 松阳县| 长泰县| 宜阳县| 南昌县| 汝阳县| 邳州市| 应城市| 通城县| 武穴市| 和龙市| 开原市| 彝良县| 思南县| 新巴尔虎右旗|