左右c++与java中国的垃圾问题的分析与解决

DionysosLai(906391500@qq.com)  2014/8/1

问题分析:

之所以会出现中文乱码问题,归根结底在于中文的编码与英文的编码方式存在差异。

在java内部是使用16bit的unicode编码(即utf-16)来表示字符串。不管英文还是中文都是2字节。

C/C++使用的是原始数据,ascii是一个字节,中文通常是GB2312编码,用2个字节表示一个汉字。

Jni内部是使用utf-8编码表示字符串的,utf-8是扁长的unicode。一般ascii是1字节。中文是3字节。

以下给出在不同字符集编码下的字节数:

英文字母:

字节数 : 1;编码:GB2312              字节数: 1;编码:GBK            字节数 : 1;编码:GB18030

字节数 : 1;编码:ISO-8859-1        字节数: 1;编码:UTF-8         字节数 : 4;编码:UTF-16

字节数 : 2;编码:UTF-16BE           字节数: 2;编码:UTF-16LE

中文汉字:

字节数 : 2;编码:GB2312              字节数: 2;编码:GBK            字节数 : 2;编码:GB18030

字节数 : 1;编码:ISO-8859-1        字节数: 3;编码:UTF-8         字节数 : 4;编码:UTF-16

字节数 : 2;编码:UTF-16BE           字节数: 2;编码:UTF-16LE

二者数据传递分析:

Java->C++数据传递

有上文可知,java使用的是utf-16编码。jvm把数据传递给jni,c++dedao的是输入參数u是jstring。此时,能够利用jni提供的两种函数,一个是GetStringUTFChars,这个函数将得到一个UTF-8编码的字符串;还有一个是GetStringChars这个将得到UTF-16编码的字符串。不管那个函数,假设字符串包括中文,都须要进一步转化成C\C++的编码格式:GB2312。

C++->java数据传递

C\C++的英文编码方式是ascii码,对于中文则是GB2312。Jni返回给java的字符串,c\c++首先应该负责把这个字符串扁长utf-8或者utf-16格式,然后通过NewStringUTF或者NewString将字符串封装成jstring,返回给java就可以。

假设没有中文字符,就仅仅有标准的ascii码值,那么使用GetStringUTFChars/NewStringUTF能够轻松搞定。由于在这样的情况下。utf-8编码和ascii编码是一致,不须要转换。

假设存在中文字符。那么在C\C++部分进行编码就是必须的,一个是把utf-8/16的编码转成GB2312。一个是把GB2312转成utf-8/16。

问题解决:

最终到解决这个问题的时刻了。(我的大斧已经饥渴难耐了)。

对于编码转换,推荐使用iconv库,iconv库是一个免费独立的编码转化库。支持多种平台。多种编码,并且其行为不论什么不受外部环境影响。使用iconv库的另外一个优点就是cocos2dx在win32平台下已经集成了其库环境,不须要开发人员额外加入。可是在Android平台就须要开发人员自己加入。至于怎样在Android平台上加入iconv库,在以下会具体解说(也能够看网上教程。基本方法都是怎样在Eclipse上加入库)。

以下给出怎样将中文编码格式GB2312,转化成utf-8编码方式。

int CCDirector::GBKToUTF8(std::string &gbkStr)
{iconv_t iconvH;    iconvH              = iconv_open("utf-8","gb2312");    if(iconvH == 0){    return -1;    }    const char* strChar = gbkStr.c_str();    const char** pin    = &strChar;    size_t strLength    = gbkStr.length();    char* outbuf        = (char*)malloc(strLength*4);    char* pBuff         = outbuf;    memset(outbuf,0,strLength*4);    size_t outLength    = strLength*4;
<span style="color:#ff6666;"><strong>#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)if(-1 == iconv(iconvH,pin,&strLength,&outbuf,&outLength)){    iconv_close(iconvH);    return -1;    }
#elseif(-1 == iconv(iconvH,(char **)pin,&strLength,&outbuf,&outLength)){    iconv_close(iconvH);    return -1;    }
#endif</strong></span>gbkStr              =   pBuff;    iconv_close(iconvH);    return 0;
}

注意红色字体代码,在win32平台和android平台传递的參数是不一样的。这个主要原因是因为pin參数是constchar**型,在java中,没有这样的类型參数。因此要强制装换成char**类型。

在Eclipse中加入iconv库

Iconv库下载地址例如以下:

Cocos2dx引擎在win32平台,本身自带了iconv库,库地址在E:\EngilshLogicGame\EnglishGame\cocos2d-x-2.2.3\cocos2dx\platform\third_party\win32,在这里面还包含其它的一些库文件,例如说网络库,解析png库等。引擎在Android平台,没有自带iconv库(个人推測原因是因为ndk自带iconv库了,因此事实上能够不用自己下载iconv库,但这里。我们给出方法是使用自己下载的iconv库),iconv库的下载地址上文已经给出。

通过更改projectproj.android/jni/Android.mk文件,将iconv库文件载入进Eclipse中。在mk文件里增加了以下两句话,如图所看到的:

注意:这里我将下载的iconv库文件放在了引擎的external文件下(当然,也能够发在别的地方,仅仅须要更改相应的文件夹文件就可以),如图所看到的:

下一步。是要更改我们下载的iconv库文件里的mk文件(假设是从我这下载的iconv库,我已经更改好了)。

更改方式,如图所看到的:

注意:画圈的两个keyword,与之前改动的proj.android/jni/Android.mk文件里的keyword是一致的。

到这里,iconv库在Android平台就加入完成了。

在之前给出的函数GBKToUTF8中。用到了iconv库函数,因此在文件里要包括iconv头文件,详细代码例如以下所看到的:

#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "iconv.h"
#else
#include "../external/libiconv/include/iconv.h"
#endif

至此,关于“关于c++与java中文乱码问题分析与解决”话题。就到此为止。希望能对大家有点帮助。

也感谢公司的同事给帮助到,一些博客和在线。

版权声明:本文博主原创文章,博客,未经同意不得转载。

左右c++与java中国的垃圾问题的分析与解决相关推荐

  1. java 与 乱码问题_透彻分析和解决一切javaWeb项目乱码问题

    前言 乱码是我们在程序开发中经常碰到且让人头疼的一件事,尤其是我们在做javaweb开发,如果我们没有清楚乱码产生的原理,碰到乱码问题了就容易摸不着头脑,无从下手. 乱码主要出现在两部分,如下: 第一 ...

  2. Postfix疯狂外发垃圾邮件之分析与解决

    本周二上班有人反应公司邮箱无法外发邮件,后来登录到服务器查看原因,不看不知道,一看吓一跳,服务器日志疯狂滚动!一看全是被其它邮件服务器拒绝的信息!由于这台服务器以前不是我管,连配置文件都find了好久 ...

  3. juc是个什么鬼(一) Java并发包详情,CAS分析,解决ABA问题

    JUC就是java.util.concurrent包,俗称java并发包 通过看JDK的API,我们发现JUC下有俩子包,分别是atomic和locks包,这篇文章重点就是看这两个包下的内容 Atom ...

  4. 中国电子垃圾市场前景风险预测与投资战略规划报告2022-2028年

    中国电子垃圾市场前景风险预测与投资战略规划报告2022-2028年 ═━┈┈━══━┈┈━══━┈┈━══━    [出版机构]:  中商经济研究网 第一章电子垃圾及所属行业的相关概述 第一节电子垃圾 ...

  5. JVM 调优实战--什么是垃圾回收及Java的自动垃圾回收GC

    什么是垃圾回收 程序的运行必然要申请内存资源,无效的对象资源如果不及时处理就会一直占用内存资源,最终将导致内存溢出,所以对内存资源的管理就变得非常重要了. C/C++语言的垃圾回收 在C/C++语言中 ...

  6. 一文搞懂JAVA与GO垃圾回收

    导语  现代高级编程语言管理内存的方式分为两种:自动和手动.像 C.C++ 等编程语言使用手动管理内存的方式,编写代码过程中需要主动申请或者释放内存:而 PHP.Java 和 Go等语言使用自动的内存 ...

  7. Java中的垃圾回收与对象生命周期

    转载自   Java中的垃圾回收与对象生命周期 1. 垃圾回收 垃圾回收是Java程序设计中内存管理的核心概念,JVM的内存管理机制被称为垃圾回收机制. 一个对象创建后被放置在JVM的堆内存中,当永远 ...

  8. ReviewForJob——java虚拟机的垃圾回收策略(个人总结)

    理解jvm的垃圾回收策略,需要解决以下3个问题 问题1:哪些内存需要回收? 问题2:什么时候进行回收? 问题3:怎样来回收? [解决问题1]哪些内存需要回收? jvm的内存区域有5大块: 1)程序计数 ...

  9. 高吞吐低延迟Java应用的垃圾回收优化

    高吞吐低延迟Java应用的垃圾回收优化 高性能应用构成了现代网络的支柱.LinkedIn有许多内部高吞吐量服务来满足每秒数千次的用户请求.要优化用户体验,低延迟地响应这些请求非常重要. 比如说,用户经 ...

  10. 【java虚拟机序列】java中的垃圾回收与内存分配策略

    在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...

最新文章

  1. 三级网络技术刷题笔记
  2. 哲学家就餐问题(如何避免死锁)(多线程版)
  3. 鼠标固定在屏幕中间_无线电竞黑科技,雷柏VT950Q游戏鼠标评测
  4. php 可视化neo4j,开源图形数据库Neo4j使用 php开发
  5. [LeetCode] 1. Two Sum
  6. 总结几个等价无穷小相关的关系运算
  7. ZoomIt 的安装及使用方法
  8. 十进制转二进制、十六进制
  9. 二级运放压摆率分析(SR)
  10. unity shader - 圣斗士星矢 人物 shader 还原 - GPA 抓帧提取资源、shader,ROOT权限、救砖、ro.debuggable=1(最终还是RenderDoc无法抓帧)
  11. 小新pro16独显版安装NVIDIA驱动
  12. 人类历史的进程vs互联网的进程
  13. OpenCV官方教程中文版
  14. 优缺点 快速扫描 硬盘监测_有了这6款mac硬盘检测工具 你就能够快速检测磁盘的状态和错误情况...
  15. Excel中按多个符号进行分列
  16. python百度识别花草_用python代码实现调用百度的免费植物识别接口
  17. 人声和乐器的频谱范围
  18. 【玩转ESP32】17、PWM调光
  19. win7安装Cajviewer后,打开文档,目录注释乱码问题解决
  20. 网页添加飘动窗口(图片链接)+ IE8下js解析错误

热门文章

  1. Visual C# 2008+SQL Server 2005 数据库与网络开发――3.1.2 C# 2005和2008之间的关系
  2. 第四次团队作业--选题
  3. TableView载入WebView的一些小技巧 By 徐
  4. 在Unity中添加图标
  5. 文件读入简单操作(C#)
  6. 标签 'http' 已声明。标签名称在批查询或存储过程内部必须唯一。
  7. SortedList 用法
  8. Centos7配置 SNMP服务(防火墙配置注意)
  9. Docker系列教程27-在生产环境中使用Docker Compose
  10. 第二章 算法 (大话数据结构)