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,©);
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)自己仔細看看上面的代碼就可以了.