android JNI C代码中文返回乱码

54 篇文章 0 订阅
32 篇文章 0 订阅

http://www.kankanews.com/ICkengine/archives/40121.shtml

现在的心情是:真想抬起脚把这电脑一脚踹了

就一个编码问题整整近3个工作日的苦憋 … 

把这个苦憋的过程记录下来,也给后来的朋友做个参考

背景:

     自己是专门从事嵌入式C开发的,因项目需要在手机上写个APP(之前也搞过一个简单的手机APP)。自己专门从事C的自然很多代码是C,该项目中后台软件也是C(需要在多个系统平台上运行),意味着android代码需要调用C代码。首先想到的自然是NDK。

– 第一步自然是搭建平台

       自己电脑有eclipse,jdk为r7,算比较新,不要动了

       下个NDK(最新为r9),很开心的是了解到自r7之后不再需要cygWin(这是在cygWin快安装好的时候才了解到的,都是因为参考教科书导致的)。

      整个环境就是:window xp + eclipse + NDK

(注:罗嗦下,NDK就是个编译器,如果java程序不在android上运行直接在PC上运行,java可直接调用VC编译的dll,那么也就不需要NDK,JNI是一套Java到C/C++的接口)

– 软件安装好了,环境配置下(baidu上有不少这方面资料,根据资料错不了)

– 把所有的C代码拷贝到android项目里的一个文件夹下,通常是jni

(这里关键是要维护好android.mk文件,首先增加减少C文件都需要更改该文件,格式如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := db
LOCAL_SRC_FILES := test1.c\
                              test2.c
LOCAL_LDLIBS    := -llog

include $(BUILD_SHARED_LIBRARY)

(如果要在C中使用Log就必须LOCAL_LDLIBS    := -llog)

– 编译后会生成libdb.so库文件

– android中载入该库并可调用其函数

接下来就是主题了(罗嗦了),C的接口中如果要返回中文,会是两个情况:

– 崩溃

– 乱码

简单说下编码(也是折腾后才知道的,如有不对请指正):

android代码:unicode-16

JNI:UTF8

C:通常是GBK

unicode-16和UTF8是同类编码,可以直接通过算法进行转换

GBK是中国特色,GBK到unicode/UTF8只能通过表映射

为了解决问题开始baidu上到处找,方法如下:

– 将文件编码改为UTF-8,修改方式:在eclipse平台上打开代码文件如:test.c,内容剪切,保存,再把内容拷贝回去,保存。然后鼠标放文件上点右键进入属性,有text file ecoding项,选择other中的UTF8编码即可。改后确实可以将中文正常返回到android代码。

问题是不可能将所有C代码换成UTF8,原因有:1、GBK–>UTF8后所有注释荒废 2、C代码中还需要读写外部文件,这个改后是否也要将外部文件转成UTF8?(扯蛋的做法)

以上方法不行,继续找:

– 很多人提到使用iconv,而且有针对window,网上有源代码(头疼),也有编译好的.dll, .lib先下了个,拿到文件后头晕了,怎么将.dll加到android中呢?继续看资料,原来是要把自己的代码在VC上编译成.dll,也就是通过dll嵌套实现iconv的接口应用,但还是这个问题,android上怎么用.dll文件,创建了个普通java app,测试下确实可行。但在android没找到办法 …

– 问题没解决,继续找,终于通过baidu  ANSI C GBK 转UTF8找到一个C写的转换函数,文件很大近2W行的代码,里面主要就是映射表,直接将其放进自己的后台软件中参与编译,(除提示文件太大外其他正常,可在起提示中将文件最大行数改下,默认是5000)编译正常,但一用立刻崩溃。测试其崩溃原因发现:

– 如果待转换字符中不带中文不崩溃,如果带中文则崩溃(不是每次都这样)

– 如果待转换字符为中文出来的数据可能为空

看源代码(这还是比较熟悉),发现该文件比较复杂,里面功能比较多,而且有些书写方式也不是自己喜欢的(这些方式在不同平台可能会出异常)。因此开始对其进行裁减,首先把映射表考过来,再将需要的几个接口考过来,把所有感觉不舒服的书写方式改成自己喜欢的方式。(代码中最大一个问题就是映射表使用的是初始化函数的栈内存,该函数退出后该内存命运也就只有上帝知道了,将该表提到函数外使用堆内存)

编译测试通过。


  声明:OSCHINA 博客文章版权属于作者,受法律保护。未经作者同意不得转载。    

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值