快捷搜索:   服务器  安全  linux 安全  MYSQL  dedecms

JAVA与C++::关于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%\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)自己仔细看看上面的代码就可以了.

顶(0)
踩(0)

您可能还会对下面的文章感兴趣:

最新评论