今回はデータ圧縮/解凍用のzlibをAndroidのネイティブ環境から利用してみる。基本的な流れは前回のSQLiteを利用したときと同じだ。
https://www.zlib.net/からzlibのソースコードをダウンロードする。今回はzlib 1.2.5を利用した。
次にEasyProjectGenerator for Android Ver 1.00を利用してAndroid NDKプロジェクトを生成して、jniフォルダ直下に「zlb」というフォルダを作る。そして、そこへダウンロードしたzlibのソースファイルのうち、上位のフォルダに入っている*.cと*.hファイルをすべて解凍する。
さらにjniフォルダ直下のソースファイルとmakefileも新しく「Test106」というフォルダを作り、そこへ移動しておく。
ここまでの操作でできたプロジェクトフォルダをEclipseにAndroidプロジェクトとして取り込んだ。
次にビルド用のAndroid.mkファイルを順次作成する。まずはjniフォルダの直下に作る。

include $(call all-subdir-makefiles)

LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libzip LOCAL_LDLIBS := -lz LOCAL_SRC_FILES := adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c include $(BUILD_STATIC_LIBRARY)

#include <string.h> #include <jni.h> #include <stdio.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> #include <zlib.h> int CompressTest(int bCompress,const char* pszDstFile,const char* pszSrcFile) { int ret; int nFd; char* pszMapped; long nFileSize; //処理対象ファイルを開く nFd = open(pszSrcFile,O_RDONLY); if(nFd < 0) return 0; //処理対象ファイルのサイズ取得 { struct stat sFileStat; ret = fstat(nFd,&sFileStat); if(ret < 0) { close(nFd); return 0; } nFileSize = sFileStat.st_size; } //処理対象ファイルをメモリマップドファイルにする pszMapped = (char*)mmap(NULL,nFileSize,PROT_READ,MAP_SHARED,nFd,0); if(pszMapped == MAP_FAILED) { close(nFd); return 0; } //メイン処理 { Bytef* pcbCompData; long nCompLen; if(bCompress) { //圧縮処理 nCompLen = nFileSize * 1.1 + 13; pcbCompData = (Bytef*)malloc(nCompLen); compress(pcbCompData,&nCompLen,pszMapped,nFileSize); } else { //解凍処理 //元サイズ取得&バッファ確保 nCompLen = *(long*)pszMapped; pcbCompData = (Bytef*)malloc(nCompLen); char* pTmp; //サイズが保存されていた分だけポインタを進めて解凍処理 pTmp = pszMapped; pTmp += sizeof(nFileSize); uncompress(pcbCompData,&nCompLen,pTmp,nFileSize - sizeof(nFileSize)); } { FILE *fp; fp = fopen(pszDstFile,"w"); if(fp) { if(bCompress) { //圧縮時は圧縮前のサイズを保存 fwrite(&nFileSize,sizeof(nFileSize),1,fp); } fwrite(pcbCompData,1,nCompLen,fp); fclose(fp); } } free(pcbCompData); } //メモリマップドファイル開放 munmap(pszMapped,nFileSize); close(nFd); return 1; } jstring Java_com_Test106_Test106Act_stringFromJNI(JNIEnv* env,jobject thiz) { //テスト用ファイル作成 FILE *fp; fp = fopen("/sdcard/test.txt","w"); if(fp) { fputs("--------------------------------------------------",fp); fputs("----------this is compress data-------------------",fp); fputs("--------------------------------------------------",fp); fputs("Test line.Test line.Test line.Test line.Test line.",fp); fputs("Test line.Test line.Test line.Test line.Test line.",fp); fputs("Test line.Test line.Test line.Test line.Test line.",fp); fputs("--------------------------------------------------",fp); fclose(fp); } //圧縮 CompressTest(1,"/sdcard/test.cmp","/sdcard/test.txt"); //解凍 CompressTest(0,"/sdcard/decomp.txt","/sdcard/test.cmp"); return (*env)->NewStringUTF(env, "Test106text"); }

LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := Test106jni LOCAL_SRC_FILES := Test106jni.c LOCAL_STATIC_LIBRARIES := libzip LOCAL_C_INCLUDES += $(call my-dir)/../zlib include $(BUILD_SHARED_LIBRARY)
以上の操作でプロジェクトの設定が終わった。ndk-buildによりネイティブコードをビルドする。
EclipseのDDMSから仮想SDカード内を見ると、圧縮前のtest.txt、圧縮したtest.cmp、解凍したdecomp.txtの3ファイルを確認できた。