<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Feeling

        三人行,必有我師焉

       ::  :: 新隨筆 :: 聯系 ::  :: 管理 ::
      185 隨筆 :: 0 文章 :: 392 評論 :: 0 Trackbacks
    網上有一篇關于JNI中文問題的文章,寫得很詳細,http://www.vckbase.com/document/viewdoc/?id=1611

    我在這里主要是想說說我碰到的一些問題,并且希望能從各位老大身上獲得答案。

    因為一直從事Java編程,基本上沒有涉及過C++的開發,最近因為開源項目SWT Extension,不得已需要用JNI來實現一些系統Native功能。但是總是需要一些Java字符串對應C++的字符串的問題。一邊情況下我都是使用SWT的TCHAR來解決問題,少部分情況需要傳遞Java String到JNI。然而少部分的這些Case總是在某些問題下出現亂碼或者異常。我一直使用的是網上比較流行的中文編碼解決方案:
    char* jstringToNative( 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 nativeTojstring( 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;
    }

    一般情況下,這兩個函數能夠很好的工作。但是在讀寫注冊表時,如果一個key的名字或者value的名字中包含了中文,jstringToNative的解決方案是不正確的,我在網上查了一下其它的關于Java訪問注冊表的開源項目,發現雖然它們都對字符串進行了處理,但依然存在著中文問題。我進行了數次嘗試,但都沒有成功。最后到了已經絕望的時候,用開頭我提到的那篇文章中里說的最不可能用到的方法將問題成功地解決了:
    char* jstringToNative( JNIEnv  *env, jstring jstr )
    {
      
    const char* pstr = env->GetStringUTFChars(jstr, false);
      
    int nLen = MultiByteToWideChar( CP_UTF8, 0, pstr, -1, NULL, NULL );
      LPWSTR lpwsz 
    = new WCHAR[nLen];    
      MultiByteToWideChar( CP_UTF8, 
    0, pstr, -1, lpwsz, nLen );
      
    int nLen1 = WideCharToMultiByte( CP_ACP, 0, lpwsz, nLen, NULL, NULL, NULL, NULL );    
      LPSTR lpsz 
    = new CHAR[nLen1];
      
    int size = 0;
      size 
    = WideCharToMultiByte( CP_ACP, 0, lpwsz, nLen, lpsz, nLen1, NULL, NULL );
      
    if( size <= 0 ){
          delete [] lpwsz;
          
    return NULL;
      }
      env
    ->ReleaseStringUTFChars(jstr, pstr );
      delete [] lpwsz;
      
    return lpsz;
    }
    問題雖然解決了,但是我卻不求甚解,為什么直接通過env拿到unicode字串,然后轉成多字節串不行,但是通過env拿到utf-8字串,然后轉成unicode字串,再將這個unicode字串轉成多字節串就能工作?

    如果大家有興趣的話,不妨試試,用JNI調用RegOpenKeyEx這個API,就能驗證我說的這個Case。哪位老大對JNI比較在行的話,可以在評論中告訴我,不甚感激。
    posted on 2008-05-04 13:17 三人行,必有我師焉 閱讀(4030) 評論(2)  編輯  收藏

    評論

    # re: JNI的中文問題 2008-05-04 15:41 Unmi
    看到了,還是需要用
    MultiByteToWideChar
    WideCharToMultiByte

    這兩個寬窄字符轉換的的 API 函數。  回復  更多評論
      

    # re: JNI的中文問題 2008-05-04 17:40 笨笨
    考慮到跨平臺兼容問題,可以考慮用ICU庫.
    更加簡單的辦法:
    先用String.getBytes()方法將String轉為byte數組給C代碼. 返回時用 new String(byte[]) 將字節數組轉為String對象.
      回復  更多評論
      


    只有注冊用戶登錄后才能發表評論。


    網站導航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    GitHub |  開源中國社區 |  maven倉庫 |  文件格式轉換 
    主站蜘蛛池模板: 精品视频免费在线| 亚洲AV无码一区二区三区人| 国产亚洲成在线播放va| 在线观看免费污视频| 亚洲中文字幕在线无码一区二区| 18禁止看的免费污网站| 久久夜色精品国产亚洲AV动态图 | 国产亚洲精品国产| 亚洲阿v天堂在线2017免费| 亚洲第一福利网站在线观看| 免费看又黄又爽又猛的视频软件| 免费人成在线观看视频播放| 美女啪啪网站又黄又免费| 亚洲AV无码一区二三区 | 免费一区二区三区在线视频| 亚洲国产成人精品久久久国产成人一区二区三区综 | 中国性猛交xxxxx免费看| 久久综合九九亚洲一区| 59pao成国产成视频永久免费| 亚洲邪恶天堂影院在线观看| 999在线视频精品免费播放观看 | 亚洲一卡2卡4卡5卡6卡在线99| 免费看国产成年无码AV片| 亚洲AV无码专区亚洲AV桃| 亚洲裸男gv网站| 无码av免费一区二区三区试看| 亚洲视频一区在线| 麻豆国产人免费人成免费视频 | 久久综合久久综合亚洲| 国产精品另类激情久久久免费| 美女黄频a美女大全免费皮| 国产aⅴ无码专区亚洲av麻豆| 99爱在线观看免费完整版| 亚洲kkk4444在线观看| 亚洲综合色视频在线观看| 久久久久久夜精品精品免费啦| 亚洲av午夜精品无码专区| 俄罗斯极品美女毛片免费播放 | h片在线免费观看| 亚洲高清一区二区三区电影| 在线亚洲人成电影网站色www|