博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android NDK移植libiconv和libxml2
阅读量:4041 次
发布时间:2019-05-24

本文共 8799 字,大约阅读时间需要 29 分钟。

使用Android NDK同时编译libxml2和libiconv库

首先做好准备工作按照如下创建好目录并准备好libiconv和libxml2的压缩文件
(我这里使用的版本为:libiconv-1.14.tar.gz libxml2-git-snapshot.tar.gz【libxml2-2.8.0】)
创建目录如下
buildlibxml2(root)
 jni->Android.mk (root-child)
 jni->main.c (root-child)
 libiconv (root-child) 
 libxml2  (root-child)
Android.mk文件如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := main
LOCAL_SRC_FILES := main.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/libxml2/include \
$(LOCAL_PATH)/libxml2/include/libxml \
$(LOCAL_PATH)/libiconv/include \
$(LOCAL_PATH)/libiconv \
$(LOCAL_PATH)/libiconv/libcharset \
$(LOCAL_PATH)/libiconv/lib \
$(LOCAL_PATH)/libiconv/libcharset/include
LOCAL_SHARED_LIBRARIES := libiconv libxml2
include $(BUILD_EXECUTABLE)
include $(call all-makefiles-under,$(LOCAL_PATH))
main.c 文件如下
#include <stdio.h>
#include <stdlib.h>
#include "libxml2/include/libxml/parser.h"
#include "libxml2/include/libxml/tree.h"

int main (int argc, char **argv)

{
  xmlDocPtr pdoc = NULL;
  xmlNodePtr proot_node = NULL,pnode = NULL,pnode1 = NULL;
 
  pdoc = xmlNewDoc (BAD_CAST "1.0");
  proot_node = xmlNewNode (NULL, BAD_CAST "root node");
  xmlNewProp (proot_node, BAD_CAST "version", BAD_CAST "1.0");
  xmlDocSetRootElement (pdoc, proot_node);
 
  pnode = xmlNewNode (NULL, BAD_CAST "child node 1");
  xmlNewChild (pnode, NULL, BAD_CAST "child child node 1", BAD_CAST "info");
  xmlAddChild (proot_node, pnode);
 
  pnode1 = xmlNewNode (NULL, BAD_CAST "child child node 1");
  xmlAddChild (pnode, pnode1);
  xmlAddChild (pnode1,xmlNewText (BAD_CAST "this will lower node, child child child node 1"));
 
  xmlNewTextChild (proot_node, NULL, BAD_CAST "child node 2", BAD_CAST "child node 2 info");
  xmlNewTextChild (proot_node, NULL, BAD_CAST "child node 3", BAD_CAST "child node info 3");
 
  xmlSaveFormatFileEnc (argc > 1 ? argv[1]:"-", pdoc, "UTF-8", 1);
 
  xmlFreeDoc (pdoc);
  xmlCleanupParser ();
  xmlMemoryDump ();
  return 0;
}
 
将libiconv库和libxml2用tar xvvzf 命令解压
进入终端 进入libiconv目录
./configure --build=x86_64-pc-linux-gnu --host=arm-linux-eabi
进入libxml2目录
./configure (用上面的命令卡到某个步骤因此用这个)
在libiconv和libxml2文件夹里面添加Android.mk文件文件分别为
libiconv Android.mk:
LOCAL_PATH:= $(call my-dir)
#libiconv.so
include $(CLEAR_VARS)
LOCAL_MODULE := libiconv
LOCAL_CFLAGS := \
  -Wno-multichar \
  -DANDROID \
  -DLIBDIR="c" \
  -DBUILDING_LIBICONV \
  -DIN_LIBRARY
LOCAL_SRC_FILES := \
 libcharset/lib/localcharset.c \
 lib/iconv.c \
 lib/relocatable.c
LOCAL_C_INCLUDES += \
  $(LOCAL_PATH)/include \
  $(LOCAL_PATH)/libcharset \
  $(LOCAL_PATH)/lib \
  $(LOCAL_PATH)/libcharset/include \
  $(LOCAL_PATH)/srclib
 
include $(BUILD_SHARED_LIBRARY)
libxml2 Android.mk:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
c14n.c catalog.c chvalid.c debugXML.c dict.c DOCBparser.c \
encoding.c entities.c error.c globals.c hash.c HTMLparser.c \
HTMLtree.c legacy.c list.c nanoftp.c nanohttp.c parser.c \
parserInternals.c pattern.c relaxng.c SAX.c SAX2.c \
threads.c tree.c trionan.c triostr.c uri.c valid.c\
xinclude.c xlink.c xmlIO.c xmlmemory.c xmlmodule.c \
xmlreader.c xmlregexp.c xmlsave.c xmlschemas.c xmlschemastypes.c xmlstring.c \
xmlunicode.c xmlwriter.c xpath.c xpointer.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/include/libxml \
$(LOCAL_PATH)/../libiconv/include \
$(LOCAL_PATH)/../libiconv \
$(LOCAL_PATH)/../libiconv/libcharset \
$(LOCAL_PATH)/../libiconv/lib \
$(LOCAL_PATH)/../libiconv/libcharset/include
LOCAL_MODULE:=libxml2
LOCAL_SHARED_LIBRARIES :=libiconv
include $(BUILD_SHARED_LIBRARY)
打开终端进入buildlibxml2目录 进行ndk-build
报错 langinfo.h No such file or directiory
查找原因查看文件 \buildlibxml2\jni\libiconv\libcharset\lib\localcharset.c
# if HAVE_LANGINFO_CODESET
#  include <langinfo.h>
# else
#  if 0 /* see comment below */
#   include <locale.h>
#  endif
# endif
解决方法将\buildlibxml2\jni\libiconv\libcharset\config.h里面
将HAVE_LANGINFO_CODESET定义改成 0
#define HAVE_LANGINFO_CODESET 0
报错
'c'undeclared identitfier
查找原因查看文件 \buildlibxml2\jni\libiconv\libcharset\lib\localcharset.c
搜索int c
将int c的定义移到get_charset_aliases函数的开头

报错 ansidecl.h  No such file or directiory

查找原因查看文件\buildlibxml2\jni\libxml2\include\libxml\xmlversion.h
#ifdef HAVE_ANSIDECL_H
#include <ansidecl.h>
#endif
解决方法打开文件\buildlibxml2\jni\libxml2\config.h
将define HAVE_ANSIDECL_H注释
//#define HAVE_ANSIDECL_H 1
报各类的如gzdopen gzopen 未定义的问题
将\buildlibxml2\jni\libxml2\config.h
HAVE_LIBZ 和HAVE_ZLIB_H
//#define HAVE_LIBZ 1
//#define HAVE_ZLIB_H 1
注释
报错 rand_r未定义
查找原因查看文件\buildlibxml2\jni\libxml2\dict.c
#ifdef HAVE_RAND_R
    rand_seed = time(NULL);
    rand_r(& rand_seed);
#else
    srand(time(NULL));
#endif
#ifdef HAVE_RAND_R
    ret = rand_r(& rand_seed);
#else
    ret = rand();
#endif
解决方法打开文件\buildlibxml2\jni\libxml2\config.h
将HAVE_RAND_R 定义注释
//#define HAVE_RAND_R 1

重新ndk-build完成成功编译

编译这2个库我只遇到以上的一些问题。还是很幸运。编译好了!准备去用一下看可以用不痛苦的是我编译的可执行文件用cygwin在不能直接用- -#哎!悲哀
直接是说cannot execute binary file
然后我就在linux下用也是一样。。。不能执行二进制文件
然后我push到android模拟器上看能不能用./main运行..悲催permission denied 没有权限
你叫我情何以堪....是不是要root模拟器....
试了一下一个命令
adb remount
adb shell
mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
cd /system/bin
cat sh > su
chmod 4755 su
su
发现不行 算了
还是好好的改JNI连接测试了。
哈哈哈!!
主activity:
package build.libxml2;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class testActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.main);
       
        TextView tv=new TextView(this);
        tv.setText("开始程序运行了!");
        Log.v("1", "程序开始了!");
        setContentView(tv);
        tv.setText("开始运行xmltest()了!");
        Log.v("1", "开始运行xmltest()了");
        natives.xmltest();
    }
}
natives.class
package build.libxml2;
import android.util.Log;
public class natives {
  static
  {
   Log.v("loadlibrary","start load iconv");
   System.loadLibrary("iconv");
   Log.v("loadlibrary","succse load iconv");
   Log.v("loadlibrary","start load xml2");
   System.loadLibrary("xml2");
   Log.v("loadlibrary","succse load xml2");
   Log.v("loadlibrary","start load main"); 
   System.loadLibrary("main");
   Log.v("loadlibrary","succse load main"); 
  }
 
  public static native void xmltest();
}
将main.c文件修改
#include <stdio.h>
#include <stdlib.h>
#include "libxml2/include/libxml/parser.h"
#include "libxml2/include/libxml/tree.h"
#include <jni.h>
#include <android/log.h>
JNIEXPORT void JNICALL Java_build_libxml2_natives_xmltest
  (JNIEnv *env, jclass jc)
{
 int i;
 __android_log_print(ANDROID_LOG_INFO,"FILE_OPT","run to testmain");
 i=testmain();
 __android_log_print(ANDROID_LOG_INFO,"FILE_OPT","fun return %d",i);
}
//int main (int argc, char **argv)
int testmain()
{
  char *szDocName="/mnt/sdcard/yy.xml";
 FILE *fp;
 fp=fopen(szDocName,"a+");
 if(fp == NULL)
 {
  fclose(fp);
  return 0;
 }
   __android_log_print(ANDROID_LOG_INFO,"FILE_OPT","file create");
  xmlDocPtr pdoc = NULL;
  xmlNodePtr proot_node = NULL,pnode = NULL,pnode1 = NULL;
 
  pdoc = xmlNewDoc (BAD_CAST "1.0");
  proot_node = xmlNewNode (NULL, BAD_CAST "root node");
  xmlNewProp (proot_node, BAD_CAST "version", BAD_CAST "1.0");
  xmlDocSetRootElement (pdoc, proot_node);
 
  pnode = xmlNewNode (NULL, BAD_CAST "child node 1");
  xmlNewChild (pnode, NULL, BAD_CAST "child child node 1", BAD_CAST "info");
  xmlAddChild (proot_node, pnode);
 
  pnode1 = xmlNewNode (NULL, BAD_CAST "child child node 1");
  xmlAddChild (pnode, pnode1);
  xmlAddChild (pnode1,xmlNewText (BAD_CAST "this will lower node, child child child node 1"));
 
  xmlNewTextChild (proot_node, NULL, BAD_CAST "child node 2", BAD_CAST "child node 2 info");
  xmlNewTextChild (proot_node, NULL, BAD_CAST "child node 3", BAD_CAST "child node info 3");
 
//xmlSaveFormatFileEnc (argc > 1 ? argv[1]:"-", pdoc, "UTF-8", 1);
  xmlSaveFormatFileEnc(szDocName,pdoc, "UTF-8", 1);
  xmlFreeDoc (pdoc);
  xmlCleanupParser ();
  xmlMemoryDump ();
  return 0;
}

将\buildlibxml2\jni\Android.mk文件修改

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := main
LOCAL_SRC_FILES := main.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/libxml2/include \
$(LOCAL_PATH)/libxml2/include/libxml \
$(LOCAL_PATH)/libiconv/include \
$(LOCAL_PATH)/libiconv \
$(LOCAL_PATH)/libiconv/libcharset \
$(LOCAL_PATH)/libiconv/lib \
$(LOCAL_PATH)/libiconv/libcharset/include
LOCAL_SHARED_LIBRARIES := libiconv libxml2
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))

进入终端进入目录buildlibxml2 ndk-build

成功生成
在AndroidManifest.xml添加文件访问权限
运行程序。
用adb pull 命令 将/mnt/sdcard/yy.xml拷出来 
用notepad查看
<?xml version="1.0" encoding="UTF-8"?>
<root node version="1.0">
  <child node 1>
    <child child node 1>info</child child node 1>
    <child child node 1>this will lower node, child child child node 1</child child node 1>
  </child node 1>
  <child node 2>child node 2 info</child node 2>
  <child node 3>child node info 3</child node 3>
</root node>
测试的例子是在网上广为流传的借用然后改写了。具体链接记不起了!
移植这个库参考了一些其他的博客知识但大多是自己撰写和整编。
成功!!!!测试成功至此libxml2和libiconv成功移植到android

转载地址:http://xtldi.baihongyu.com/

你可能感兴趣的文章
[Mac]Mac 操作系统 常见技巧
查看>>
苹果Swift编程语言入门教程【中文版】
查看>>
捕鱼忍者(ninja fishing)之游戏指南+游戏攻略+游戏体验
查看>>
iphone开发基础之objective-c学习
查看>>
iphone开发之SDK研究(待续)
查看>>
计算机网络复习要点
查看>>
Variable property attributes or Modifiers in iOS
查看>>
NSNotificationCenter 用法总结
查看>>
C primer plus 基础总结(一)
查看>>
剑指offer算法题分析与整理(一)
查看>>
剑指offer算法题分析与整理(三)
查看>>
Ubuntu 13.10使用fcitx输入法
查看>>
pidgin-lwqq 安装
查看>>
mint/ubuntu安装搜狗输入法
查看>>
C++动态申请数组和参数传递问题
查看>>
opencv学习——在MFC中读取和显示图像
查看>>
retext出现Could not parse file contents, check if you have the necessary module installed解决方案
查看>>
Matlab与CUDA C的混合编程配置出现的问题及解决方案
查看>>
PaperDownloader——文献命名6起来
查看>>
如何将PaperDownloader下载的文献存放到任意位置
查看>>