使用NDK移植/编译开源库(2)zlib的编译
来源:互联网 发布:linux开机启动zookeep 编辑:程序博客网 时间:2024/05/18 02:57
说明:
android的NDK本来就提供了zlib库,但是由于zlib相对简单,所以我第一次编译的就是zlib,只是为了了解一下大概如何编译的思路。
这里使用的zlib的版本是zlib-1.2.3。
(1)使用ndk-build的方式
解压zlib包后,将其放入JNI文件夹下,目录树结构如下:
NDK#tree -L 3.├── prj_zlib│ └── jni│ └── zlib-1.2.3└── zlib-1.2.3.tar在jni目录下,新建Android.mk(注意大写)文件,其内容如下:
LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)include $(CLEAR_VARS)LOCAL_SRC_FILES := mytest.cLOCAL_C_INCLUDES := \ $(LOCAL_PATH) \ $(LOCAL_PATH)/..LOCAL_STATIC_LIBRARIES := libzlibLOCAL_MODULE := libmyzlibtestinclude $(BUILD_SHARED_LIBRARY)include $(call all-makefiles-under,$(LOCAL_PATH))
其中,mytest.c为使用JNI封装zlib函数的测试例子,内容如下(根据需要去调用):
#include <jni.h>#include "zlib.h"#include <string.h>jstring chartojstring( JNIEnv* env, const char* pat){ /*jclass strClass = (*env)->FindClass(env,"java/lang/String;"); jmethodID ctorID = (*env)->GetMethodID(env,strClass, "<init>", "([BLjava/lang/String;)V"); jbyteArray bytes = (*env)->NewByteArray(env, strlen(pat)); (*env)->SetByteArrayRegion(env,bytes, 0, strlen(pat), (jbyte*)pat); jstring encoding = (*env)->NewStringUTF(env,"utf-8"); return (jstring)(*env)->NewObject(env,strClass, ctorID, bytes, encoding); */ /* jstring stoJstring(JNIEnv* env, const char* pat) { jclass strClass = env->FindClass("Ljava/lang/String;"); jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V"); jbyteArray bytes = env->NewByteArray(strlen(pat)); env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat); jstring encoding = env->NewStringUTF("utf-8"); return (jstring)env->NewObject(strClass, ctorID, bytes, encoding); } */ return (*env) -> NewStringUTF(env, pat);}char* jstringTostring(JNIEnv* env, jstring jstr) { char* rtn = NULL; jclass clsstring = (*env)->FindClass(env, "java/lang/String"); jstring strencode = (*env)->NewStringUTF(env, "utf-8"); jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid, strencode); jsize alen = (*env)->GetArrayLength(env, barr); jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE); if (alen > 0) { rtn = (char*)malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; } (*env)->ReleaseByteArrayElements(env, barr, ba, 0); return rtn; }jbyteArray Java_com_hello_zlib_ZlibActivity_compressStr(JNIEnv* env, jobject thiz, jstring str){ char* strSrc = jstringTostring(env, str); Byte buff[1024]={0}; unsigned long bufLen = sizeof(buff)/sizeof(buff[0]); int ret = compress(buff, &bufLen, strSrc, strlen(strSrc) + 1); if (Z_OK != ret) { memcpy(buff, "error", strlen("error")+1 ); } jbyteArray retArray = (*env)->NewByteArray(env, bufLen); (*env)->SetByteArrayRegion(env, retArray, 0, bufLen, buff); return retArray;}jstring Java_com_hello_zlib_ZlibActivity_uncompressStr(JNIEnv* env, jobject thiz, jbyteArray bArray){ jsize length = (*env)->GetArrayLength(env, bArray); jbyte* pArrayByte = (*env)->GetByteArrayElements(env, bArray, 0); unsigned char buff[1024]={0}; unsigned long bufLen = sizeof(buff)/sizeof(buff[0]); int ret = uncompress(buff, &bufLen, pArrayByte, length);/* if (Z_OK != ret) { memcpy(buff, "error", strlen("error")+1); }*/ if (Z_DATA_ERROR == ret) { memcpy(buff, "data_error", strlen("data_error")+1); } if (Z_BUF_ERROR == ret) { memcpy(buff, "buf_error", strlen("buf_error")+1); } if (Z_MEM_ERROR == ret) { memcpy(buff, "mem_error", strlen("mem_error")+1); } return chartojstring(env, buff);} jstring Java_com_hello_zlib_ZlibActivity_getVersion(JNIEnv* env, jobject thiz){ const char* version= zlibVersion(); return chartojstring(env, version);}在jni下的zlib-1.2.3文件夹下新建Android.mk,内容如下:
LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES := adler32.c compress.c crc32.c deflate.c gzio.c infback.c inffast.c inflate.c inftrees.c minigzip.c trees.c uncompr.c zutil.cLOCAL_MODULE:= libzlibinclude $(BUILD_STATIC_LIBRARY)最后,整个”工程“目录树如下(说明,只有在上面的Android.mk中列举的相关的c文件和对应的h文件对编译有用,所以下面显示的目录树将原本zlib源码中的其它无关文件和文件夹删除了):
$tree.├── prj_zlib│ └── jni│ ├── Android.mk│ ├── mytest.c│ └── zlib-1.2.3│ ├── adler32.c│ ├── Android.mk│ ├── compress.c│ ├── crc32.c│ ├── crc32.h│ ├── deflate.c│ ├── deflate.h│ ├── example.c│ ├── gzio.c│ ├── infback.c│ ├── inffast.c│ ├── inffast.h│ ├── inffixed.h│ ├── inflate.c│ ├── inflate.h│ ├── inftrees.c│ ├── inftrees.h│ ├── minigzip.c│ ├── trees.c│ ├── trees.h│ ├── uncompr.c│ ├── zconf.h│ ├── zconf.in.h│ ├── zlib.3│ ├── zlib.h│ ├── zutil.c│ └── zutil.h└── zlib-1.2.3.tar3 directories, 30 files
然后,就可以进行编译了,如下:
$lsprj_zlib zlib-1.2.3.tar$cd prj_zlib/$lsjni$NDK/ndk-buildCompile thumb : myzlibtest <= mytest.cCompile thumb : zlib <= adler32.cCompile thumb : zlib <= compress.cCompile thumb : zlib <= crc32.cCompile thumb : zlib <= deflate.cCompile thumb : zlib <= gzio.cCompile thumb : zlib <= infback.cCompile thumb : zlib <= inffast.cCompile thumb : zlib <= inflate.cCompile thumb : zlib <= inftrees.cCompile thumb : zlib <= minigzip.cCompile thumb : zlib <= trees.cCompile thumb : zlib <= uncompr.cCompile thumb : zlib <= zutil.cStaticLibrary : libzlib.aSharedLibrary : libmyzlibtest.soInstall : libmyzlibtest.so => libs/armeabi/libmyzlibtest.so$下面是在android中调用上面的.so中函数的代码:
package com.hello.zlib;import android.app.Activity;import android.os.Bundle;import android.widget.TextView;public class ZlibActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String version = getVersion(); String comSrc = "中文测试EnglishTesting1234567890\n" + "中文测试EnglishTesting1234567890\n" + "中文测试EnglishTesting1234567890\n" + "中文测试EnglishTesting1234567890\n" + "中文测试EnglishTesting1234567890"; byte[] comByte = compressStr(comSrc); String uncomStr = uncompressStr(comByte); String str = "Ther version of zlib is: " + version + "\n\n"; str = str + "SrcStr: \n" + comSrc + "\nLen: " + comSrc.length() + "\n\n"; str = str + "Com byte: \n" + comByte + "\nLen: " + comByte.length + "\n\n"; str = str + "Un-com Str: \n" + uncomStr + "\nLen: " + uncomStr.length() + "\n\n"; TextView tx = (TextView) findViewById(R.id.txt); tx.setText(str); } public native String getVersion(); public native byte[] compressStr(String str); public native String uncompressStr(byte b[]); static { System.loadLibrary("myzlibtest"); }}这样,就在jni下的libs中生成了libmyzlibtest.so了,编译完成。
(2)使用GCC
略。
- 使用NDK移植/编译开源库(2)zlib的编译
- 使用NDK移植/编译开源库(3)libpng的编译
- 使用NDK移植/编译开源库(4)libjpeg的编译
- 使用NDK移植/编译开源库(5)sqlite3的编译
- 使用NDK移植/编译开源库(1)准备
- zlib的编译和使用
- 编译和使用zlib
- Zlib-基于source file的编译使用
- zlib库编译使用,编译好的LIB静态库
- Android NDK编译librtmp 三重奏 -- (一)编译zlib
- 如何编译和使用zlib
- ffmpeg移植NDK编译汇总
- zlib编译
- 编译zlib
- 编译zlib
- zlib编译
- 使用 Android NDK 的交叉编译工具链移植 C/C++ 项目到安卓平台
- 使用 Android NDK 的交叉编译工具链移植 C/C++ 项目到安卓平台
- web.xml
- [转] 心态是最大的本钱;人无完人,重要的是怎么做人
- Ant打可执行jar包指南
- Python中调用C++函数
- 使用stringstream时需要注意的一点
- 使用NDK移植/编译开源库(2)zlib的编译
- winform中坐标系转换的问题,获取某点在屏幕中的绝对位置等
- 国外知名网站Stackoverflow 历时两年评选出11本对程序员最有影响力的书籍
- Win7的评分工具WinSAT
- spring-ibatis-Struts-Hibernate 架构图
- 关于C++里面折叠代码的两招
- C语言的发展史
- Spring AOP事务管理(使用切面把事务管理起来)
- 服务中的信号量和进程锁