在JNI調用C實現的本地方法時,咱們曾經介紹過直接修改控制檯代碼頁的方式解決中文亂碼問題(文章參見:http://wiki.xuetang9.com/?p=5254 ),可是到了C++實現,這個方法又無論用了,折騰了一個下午,終於找到了解決問題的方法,分享以下:微信
一、相關概念ide
你們都知道,Java內部採用的是16位Unicode編碼來表示字符串,中英文都採用2字節;而JNI內部是使用UTF-8編碼來表示字符串,UTF-8編碼其實就是Unicode編碼的一個變長版本(對應關係參見文章:http://wiki.xuetang9.com/?p=5207 ),通常的ASCII字符佔1個字節,中文漢字是3個字節;C/C++使用的是原始數據,ASCII字符就是一個字節,中文通常是GB2312編碼,使用兩個字節表示一箇中文字符。明確了概念,操做就比較清楚了。下面根據字符流的方向來分別說明一下:函數
1-1:從Java 到 C/C++編碼
這種狀況下,Java調用的時候使用的是UTF-16編碼的字符串,JVM把這個字符串傳給JNI,C/C++獲得的輸入是jstring,這個時候,能夠利用JNI提供的兩種函數,一個是GetStringUTFChars,這個函數將獲得一個UTF-8編碼的字符串;另外一個是etStringChars這個將獲得UTF-16編碼的字符串。不管哪一個函數,獲得的字符串若是含有中文,都須要進一步轉化成GB2312的編碼。示意圖以下:3d
1-2:從C/C++ 到 Javacode
從JNI返回給Java的字符串,C/C++首先就會負責把字符串轉換爲UTF-8或UTF-16的格式,而後經過NewStringUTF()或NewString()方法將字符串封裝成jstring,返回給Java就能夠了:blog
若是字符串中不含中文字符,只是標準ASCII碼,使用GetStringUTFChars()/NewStringUTF()方法就能夠搞定了,由於這個狀況下,UTF-8編碼和ASCII編碼是一致的,不須要轉換。可是若是字符串中存在中文字符,那麼就必須在C/C++程序中進行轉碼操做。這裏要說明一下:Linux和Win32都支持wchar,這個實際上就是寬度爲16位的Unicode編碼UTF-16。因此,若是咱們的C/C++程序中徹底使用wchar類型,理論上就不須要這種硬轉換了。可是實際上,你們在寫程序的時候不可能徹底用wchar來取代char,因此就目前大多數應用而言,轉換仍然是必須的。字符串
二、轉換方法:須要包含的頭文件:string
使用wide char 類型來作轉換:亂碼
更多幹貨筆記關注微信公衆號 : 老九學堂