JAVA與C++::關於JNI中文字符串操作問題總結

JAVA與C++::關於JNI中文字符串操作問題總結

/**
 *
 *@Author ZosaTapo
 *
 *@E-Mail [email protected]
 *
 *@QQ     1670967
 *
 */

[問題簡單背景]

使用JAVA編程有時候需要使用JNI來實現效率方面或者是其他方面的問題。在JNI使用中不得不面臨
的問題就是中文問題(如果你是老外,並且不關心中國建設,那就不用看了;或者你已經知道如何解決
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
的話,你也不用看了),JAVA採用UNICODE來支持運行時,當然類文件的保存格式是UTF-8。
~~~~~~~~~~~~~~~~~

當然了你用pure JAVA也不會出現問題的,其他出現的問題也不包含在今天的論題中(比如文件保存的字符集
或者是WEB開發中的中文問題)。當我們需要使用JAVA和本地環境混合編程時候,問題就來了:

(1)JAVA如何傳遞UNICODE字符串到本地環境
(2)本地環境如何傳遞UNICODE字符到JAVA環境

當然了,中國人我只關心中文在之間的轉化,英文很好辦,因爲沒有問題的,其他語言偶不關心。

[測試環境說明]

下面說明一下本人使用的環境。
(1)WINDOWS2000 Professional/512M DDR RAM/P4 2.0G
(2)SUN JDK1.4.0
(3)VC++ 6.0 /SP5

[測試過程說明]

============================
編寫JAVA程序,得到接口文件
============================
//jni.java

public class jni
{
  static
  {
    System.loadLibrary("jni");
  }
 
  public native String getChinese(String str);
 
  public static void main(String args[])
  {
    jni j=new jni();
    System.err.println("[從NATIVE環境返回字符]"+j.getChinese("測"));
   
    char ch='測';
    System.err.println("[在JAVA環境中]'測'的UNICODE="+(int)ch);
  }
}

編譯JAVA程序
%JAVA_HOME%/bin/javac jni.java

得到接口文件
%JAVA_HOME%/bin/javah jni

//jni.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jni */
#ifndef _Included_jni
#define _Included_jni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jni
 * Method:    getChinese
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_jni_getChinese
  (JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif

============================
編寫本地實現
============================
具體怎麼寫DLL等,我看我就不用講了,所以我只是簡單
摘寫相關的代碼。

//#include "jni.h"
JNIEXPORT jstring JNICALL Java_jni_getChinese
(JNIEnv *env, jobject obj, jstring s)
{
 jchar * newstring;
 jstring ret=0;
 /*
 //-- 測試第三部分 --
 newstring=new jchar[1];
 newstring[0]=27979;//中文'測'的unicode
 ret=env->NewString(newstring,1);
 delete []newstring;
 */

 //-- 測試第一部分 --
 wchar_t* p=L"測";
 printf("/n[在NATIVE環境中]'測'的UNICODE=%d",*p);
 newstring=(jchar*)p;
 ret=env->NewString(newstring,1);

 //-- 測試第二部分 --
 const jchar * jstr;
 jboolean copy='1';

 jstr=env->GetStringChars(s,&copy);
 wprintf(L"/n[從JAVA環境傳入字符]%s/n",jstr);
 env->ReleaseStringChars(s,jstr);

 return ret;
}

============================
運行測試程序
============================
把編譯後的DLL文件放在恰當的位置(不會不知道什麼是恰當的位置吧)。

如果你真的不知道的話,告訴你一個最簡單的方式,看看
java.library.path屬性就知道了。

程序運行結果。
%JAVA_HOME%/bin/java jni

[在NATIVE環境中]'測'的UNICODE=27979
[[從NATIVE環境返回字符]測
[在JAVA環境中]'測'的UNICODE=27979

============================
解釋測試過程
============================
由於JAVA是UNICODE運行時的,我很懶,自己不可能寫字節碼與UNICODE之間的轉碼程序。
網上有的,實際上很多TELNET客戶端程序都是自己帶有的。但是我們就運行在WINDOWS環境下
當然就直接使用他的UNICODE支持了(UNIX環境當然也有相應的支持)。

(1)確認我們使用UNICODE支持。請仔細閱讀TCHAR.h文件,不管你是爲了本次測試還是爲了提高你WINDOWS編程的認識


類型使用wchar_t作爲本地字符UNICODE支持。

(2)自己熟悉一下JNI接口關於UTF和UNICODE操作的相關函數。

(3)自己仔細看看上面的代碼就可以了.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章