JNI 中文字符串传递(转)

源:JNI 中文字符串传递

因为项目编码中通过JNI传递中文字符时出现乱码问题,特搜集了相关资料,整理如下:

java内部是使用16bit的unicode编码(UTF-16)来表示字符串的,无论中文英文都是2字节;
jni内部是使用UTF-8编码来表示字符串的,UTF-8是变长编码的unicode,一般ascii字符是1字节,中文是3字节;
c/c++使用的是原始数据,ascii就是一个字节了,中文一般是GB2312编码,用两个字节来表示一个汉字。

1、java --> c/c++
这种情况中,java调用的时候使用的是UTF-16编码的字符串,jvm把这个字符串传给jni,c/c++得到的输入是jstring,这个时候,可以利用jni提供的两种函数,一个是GetStringUTFChars,这个函数将得到一个UTF-8编码的字符串;另一个是GetStringChars这个将得到UTF-16编码的字符串。无论那个函数,得到的字符串如果含有中文,都需要进一步转化成GB2312的编码。

在C++编写的DLL文件中添加如下转换函数:

char * JStringToCharArray(JNIEnv * pJNIEnv, jstring jstr)
{
    jsize len = pJNIEnv->GetStringLength( jstr );
    const jchar * jcstr = pJNIEnv->GetStringChars( jstr, NULL );

    int size = 0;
    char * str = ( char * )malloc( len * 2 + 1 );
    if ( (size = WideCharToMultiByte( CP_ACP, 0, LPCWSTR( jcstr ), len, str, len * 2 + 1, NULL, NULL ) ) == 0 )
        return NULL;

    pJNIEnv->ReleaseStringChars( jstr, jcstr );

    str[ size ] = 0;
    return str;
}

假设DLL中以下这个函数接受到JAVA传递的带有中文的字符串jMsg,处理如下:

JNIEXPORT void JNICALL Java_Test_hello(JNIEnv * env, jclass obj, jstring jMsg)
{
       //若使用const char *strMsgPtr = env->GetStringUTFChars( jMsg , 0)则会出错
       char * strMsgPtr = JStringToCharArray( env, jMsg );   //使用上面提供的转换函数接收字符串

       /*
         接下来便可使用strMsgPtr做你所需要的处理
      */
}

2、c/c++ --> java
jni返回给java的字符串,c/c++首先应该负责把这个字符串变成UTF-8或者UTF-16格式,然后通过NewStringUTF或者NewString来把它封装成jstring,返回给java就可以了。
如果字符串中不含中文字符,只是标准的ascii码,那么用GetStringUTFChars/NewStringUTF就可以搞定了,因为这种情况下,UTF-8编码和ascii编码是一致的,不需要转
但是如果字符串中有中文字符,那么在c/c++部分进行编码转换就是一个必须了。

转载自: http://hi.baidu.com/ivy_jing/blog/item/1a2d90899712f119c8fc7a29.html

时间: 2024-12-28 01:39:01

JNI 中文字符串传递(转)的相关文章

PHP 统计中文字符串的长度

中文网站一般会选择两种编码:gbk/gb2312或是utf-8. gbk编码下每个中文字符所占字节为2,例: $zhStr = ‘您好,中国!’; echo strlen($zhStr); // 输出:12 UTF-8编码下每个中文字符占3个字节. $zhStr = ‘您好,中国!’; echo strlen($zhStr); // 输出:18 那么如何计算这组中文字符串的长度呢?有人可能会说gbk下获取中文字符串长度除以2,utf-8编码下除以3不就行了吗?但是您要考虑字符串并不老实,99%的

PHP截取中文字符串不出现?号的解决方法[原创]

PHP截取中文字符串不出现?号的解决方法[原创] 大 | 中 | 小 [不指定 2007-8-15 18:51 | by 张宴 ] [文章作者:张宴 本文版本:v1.0 最后修改:2007.08.15 转载请注明出处:http://blog.zyan.cc] 当PHP截取中英文混合字符串时,最后一个汉字经常被拆成两半,例:截取字符串的前18个字 view plainprint? <?php $text = "1欢迎访问sina新浪播客"; $value = substr($tex

php中文字符串截取方法实例总结

本文实例总结了php中文字符串截取方法,非常实用的技巧.具体方法分析如下: 1.使用mbstring扩展库的mb_substr截取就不会出现乱码了. 2.自己书写截取函数,但效率不如用mbstring扩展库来得高. 3.如果仅是为了输出截取的串,可用如下方式实现:substr($str, 0, 30).chr(0). substr()函数可以分割文字,但要分割的文字如果包括中文字符往往会遇到问题,这时可以用mb_substr()/mb_strcut这个函 数,mb_substr()/mb_str

php中计算中文字符串长度、截取中文字符串

在做PHP开发的时候,由于我国的语言环境问题,所以我们常常需要对中文进行处理.在PHP中,我们都知道有专门的mb_substr和mb_strlen函数,可以对中文进行截取和计算长度,但是,由于这些函数并非PHP的核心函数,所以,它们常常有可能没有开启.当然,如果是用的自己的服务器,则只要在php.ini中开启即可.如果是用的虚拟主机,而服务器又没有开启这方面的函数的话,那就需要我们自己写出点适合咱国情的函数来了. 以下几个函数用起来颇为顺手的.不过要知道,得在utf-8环境下使用. header

自定义一个函数截取中文字符串

/** * 截取中文字符串 * @param unknown $str 要截取的字符串 * @param unknown $encode 字符编码 * @param unknown $start 开始位置 * @param string $len 要截取的长度 * @return string */function getStr($str,$encode,$start,$len=null){ switch ($encode) { case 'utf8':$num = 3;break; case

c/c++ 中文字符串转Unicode和UTF8

1. 描述 在windows上做系统编程,少不了会遇到处理中文字符串的问题.而大多时候中文汉字都是以多字节编码的方式展现的.为了实现更好的兼容性或一些特殊的需求,(比如在网页上显示.)常需要将其转换成unicode或者utf8的格式. 2. 代码示例 2.1 中文字符串转Unicode /************************************************************************ *int CN2Unicode(char *input,wcha

android中使用jni对字符串加解密实现分析

android中使用jni对字符串加解密实现分析 最近项目有个需求,就是要对用户的敏感信息进行加密处理,比如用户的账户密码,手机号等私密信息.在java中,就对字符串的加解密我们可以使用AES算法加密字符串,使用它的好处就不必多说了,但我们又知道android的源代码是可以被反编译的,所以使用纯Java方式的AES加密是不安全的,所以想到了使用android中的jni来对字符串加解密处理,它会产生一个.so文件,更重要的是它通过C/C++代码实现,所以安全行比较高,它可以被反编译成机器码,但几乎

[C/C++]_[VS2010源码中使用UTF8中文字符串被转码为ANSI的问题]

场景: 1.本以为vs设置了源文件的UTF8编码,代码中出现的中文字符串就一定是utf8编码了,可惜不是,如果源码中出现了中文字符串,会在内存中转码为ANSI编码. Unicode(UTF8带签名) 代码页(65001),从菜单->文件->高级保存选项 设置. 例子: char path[] = "resources\\中文\\"; for(int i = 0; i < strlen(path); ++i) { printf("0x%x,",(un

php中文字符串反转

1 <?php 2 header("content-type:text/html;charset=utf-8"); 3 /** 4 此函数的作用是反转中文字符串 5 mb_strlen() 获取字符的长度 6 mb_substr() 获取字符的单个元素 7 krsort() 按照键值逆序排序数组 8 implode() 将数组拼接为字符串 9 explode() 使用字符串分隔字符串 10 */ 11 function str_rev_gb($str){ 12 //判断输入的是不