编译iconv字符转换库使用NDK(CMakeLists.txt)方式

   上篇文章中记录了使用make install方式生成我们需要的.a静态库

通过这种方式生成的静态库之后,还是得手动将include头文件与.a文件再次使用cmake配制下,然后在ndk中生成我们想要的so库,我觉得还是比较麻烦,那有没有更简单的方式呢?通过cmake配制生成我们想要 的so,一步到位不是更好么?

源代码路径:android_iconv

前面生成config.h文件配制文件的过程与上篇文章相同

配制好ndk交叉编译环境后,使用sh ./configurate 使用生成config.h,然后把所有的文件拷到你工程的main/cpp目录下面

编写CMakeLists.txt文件

#最小版本号
CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1)

#字符编码转换
project(iconv)

add_compile_options(
        -Wno-multichar
        -DANDROID
        -D_ANDROID
        -DLIBDIR=\"\"
        -DBUILDING_LIBICONV
        -DIN_LIBRARY
)


include_directories(
        ${CMAKE_CURRENT_SOURCE_DIR}
        ${CMAKE_CURRENT_SOURCE_DIR}/include
        ${CMAKE_CURRENT_SOURCE_DIR}/libcharset
        ${CMAKE_CURRENT_SOURCE_DIR}/lib
        ${CMAKE_CURRENT_SOURCE_DIR}/libcharset/include
        ${CMAKE_CURRENT_SOURCE_DIR}/srclib
        )



add_library( # Sets the name of the library.
        iconv

        # Sets the library as a static library.
        SHARED

        # Provides a relative path to your source file(s).
        ${CMAKE_CURRENT_SOURCE_DIR}/lib/iconv.c
        ${CMAKE_CURRENT_SOURCE_DIR}/libcharset/lib/localcharset.c
        ${CMAKE_CURRENT_SOURCE_DIR}/lib/relocatable.c

        )

 config.h的生成角本,还是贴一下:

#!/bin/sh
# iconv/android_build.sh
# Compiles iconv for Android
# Make sure you have NDK defined in .bashrc or .bash_profile

export CC="arm-linux-androideabi-gcc --sysroot=$SYSROOT"
export LD="arm-linux-androideabi-ld"
export AR="arm-linux-androideabi-ar"
export RANLIB="arm-linux-androideabi-ranlib"
export STRIP="arm-linux-androideabi-strip"
export CPP="arm-linux-androideabi-gcc -E"

sh ./configure --prefix="你工程的绝对路径/libs" \
--host=arm-linux-eabi CPPFLAGS="-I${SYSROOT}/usr/include" CFLAGS="--sysroot $SYSROOT" \
LDFLAGS="-Wl,-rpath-link=$NDK/platforms/android-21/arch-arm/usr/lib/ -L$NDK/platforms/android-21/arch-arm/usr/lib/" LIBS="-lc"

最后完事

您就可以愉快的使用iconv作各种字符集转换了。哈哈

 

贴下转换代码:

#include "iconv.h"

#include <android/log.h>

#include <jni.h>

#define LOG_TAG "test"

static  int debug = 1;

#define LOGI(...) if(debug) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGW(...) if(debug) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define LOGE(...) if(debug) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

bool utf8_to_bg2312 ( char *inbuf, int *inlen, char *outbuf, int *outlen)
{

    /* 目的编码, TRANSLIT:遇到无法转换的字符就找相近字符替换
     *           IGNORE :遇到无法转换字符跳过*/
    char *encTo = "BG2312//IGNORE";
    /* 源编码 */
    char *encFrom = "UTF-8";

    /* 获得转换句柄
     *@param encTo 目标编码方式
     *@param encFrom 源编码方式
     *
     * */
    iconv_t cd = iconv_open (encTo, encFrom);
    if (cd == (iconv_t)-1)
    {
        LOGE("iconv_open failed: from: %s, to: %s: %s",
             encFrom, encTo, strerror(errno));
        return false;
    }

    /* 需要转换的字符串 */
    LOGE("inbuf=%s\n", inbuf);

    /* 打印需要转换的字符串的长度 */
    LOGE("inlen=%d\n", *inlen);

    /* 由于iconv()函数会修改指针,所以要保存源指针 */
    char *tmpin = inbuf;
    char *tmpout = outbuf;
    size_t insize = *inlen;
    size_t outsize = *outlen;

    /* 进行转换
     *@param cd iconv_open()产生的句柄
     *@param srcstart 需要转换的字符串
     *@param inlen 存放还有多少字符没有转换
     *@param tempoutbuf 存放转换后的字符串
     *@param outlen 存放转换后,tempoutbuf剩余的空间
     *
     * */
    size_t ret = iconv (cd, &tmpin, reinterpret_cast<size_t *>(inlen), &tmpout,
                        reinterpret_cast<size_t *>(outlen));
    if (ret == -1)
    {
        LOGE ("iconv");
        return false;
    }

    /* 存放转换后的字符串 */
    LOGE("outbuf=%s\n", outbuf);

    //存放转换后outbuf剩余的空间
    LOGE("outlen=%d\n", *outlen);

    int i = 0;

    for (i=0; i<(outsize- (*outlen)); i++)
    {
        //printf("%2c", outbuf[i]);
        LOGE("%x\n", outbuf[i]);
    }

    /* 关闭句柄 */
    iconv_close (cd);

    return true;
}

使用非iconv转换utf8到unicode代码实现


int myUTF8_to_UNICODE(int16 * unicode,  const char* utf8, int len)
{
    int length;
     const char* t = utf8;

    length = 0;
    while (utf8 - t < len){
        //one byte.ASCII as a, b, c, 1, 2, 3 ect
        if ( *(unsigned char *) utf8 <= 0x7f ) {
            //expand with 0s.
            *unicode++ = *utf8++;
        }
            //2 byte.
        else if ( *(unsigned char *) utf8 <= 0xdf ) {
            *unicode++ = ((*(unsigned char *) utf8 & 0x1f) << 6) + ((*(unsigned char *) (utf8 + 1)) & 0x3f);
            utf8 += 2;
        }
            //3 byte.Chinese may use 3 byte.
        else {
            *unicode++ = ((int) (*(unsigned char *) utf8 & 0x0f) << 12) +
                         ((*(unsigned char *) (utf8 + 1) & 0x3f) << 6) +
                         (*(unsigned char *) (utf8 + 2) & 0x3f);
            utf8 += 3;
        }
        length++;
    }

    *unicode = 0;

    return (length);
}

需要注意iconv在android中不支从其它编码转到unicode编码,这是实际测试的结果,总在iconv_open是返回非法参数问题,不过在android中发现也不用转码,从java层传到jni层默认就是unicode编码的,确实绕了个弯弯

 

  1. http://www.cppblog.com/lf426/archive/2008/03/31/45796.html
  2. https://blog.csdn.net/a345017062/article/details/8068917
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值