龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > C/C++开发 >

JAVA与C++::关于JNI中文字符串操作问题总结

时间:2009-12-22 15:42来源:未知 作者:admin 点击:
分享到:
[问题简单背景] 使用Java编程有时候需要使用JNI来实现效率方面或者是其他方面的问题。在JNI使用中不得不面临 的问题就是中文问题(假如你是老外,并且不关心中国建设,那就不用看了;或

  [问题简单背景]

  

  

使用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%injavac jni.java

  

  

得到接口文件

  

%JAVA_HOME%injavah jni

  

  

//jni.h

  

  

/* DO NOT EDIT THIS FILE - it is machine generated */

  

#include

  

/* 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("

[在NATIVE环境中]'测'的UNICODE=%d",*p);

  

  

newstring=(jchar*)p;

  

ret=env->NewString(newstring,1);

  

  

//-- 测试第二部分 --

  

const jchar * jstr;

  

jboolean copy='1';

  

  

jstr=env->GetStringChars(s,©);

  

wprintf(L"

[从JAVA环境传入字符]%s

",jstr);

  

env->ReleaseStringChars(s,jstr);

  

  

return ret;

  

}

  

  

============================

  

运行测试程序

  

============================

  

把编译后的DLL文件放在恰当的位置(不会不知道什么是恰当的位置吧)。

  

  

假如你真的不知道的话,告诉你一个最简单的方式,看看

  

java.library.path属性就知道了。

  

  

程序运行结果。

  

%JAVA_HOME%injava 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)自己仔细看看上面的代码就可以了.

  

精彩图集

赞助商链接