android ndk 生成so
来源:互联网 发布:淘宝钻展设计 编辑:程序博客网 时间:2024/06/05 03:57
Unzip.java
package com.android.xxx;import android.util.Log;class Unzip{ private static final String TAG = "Unzip"; public static boolean unzipSOFile() { Log.d("ZLoader", "Unzip::unzipSOFile");return nativeUnzipSOFile();}public static void loadLibCompleted() {Log.d("ZLoader", "Unzip::loadLibCompleted");nativeLoadLibCompleted();} private static native boolean nativeUnzipSOFile(); private static native void nativeLoadLibCompleted();}
c++文件, 使用mmm生成so文件
Unzip.cpp
#define LOG_TAG "Unzip"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include "zlib.h"#include <jni.h>#include <string.h>#include "base/logging.h"#include <android/log.h> namespace android {namespace {#define BUFFER_SIZE 16384#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))#define COMPILE_ASSERT(expr, err) static const char err[(expr) ? 1 : -1] = "";bool Compress(const char * DestName,const char *SrcName){ if (!DestName || !SrcName) { __android_log_print(ANDROID_LOG_DEBUG, "Tag", "Parameters error: DestName=%p, SrcName=%p\n", DestName, SrcName); return false; } FILE * fp_in = NULL; int len = 0; char buf[BUFFER_SIZE]; if (NULL == (fp_in = fopen(SrcName,"rb"))) { __android_log_print(ANDROID_LOG_DEBUG, "Tag", "Can not open file: %s", SrcName); return false; } ///////////////////////////////////////////// gzFile out = gzopen(DestName,"wb6f"); if (out == NULL) { __android_log_print(ANDROID_LOG_DEBUG, "Tag", "Can not open file: %s", DestName); return false; } bool re = true; for (;;) { len = fread(buf,1,sizeof(buf),fp_in); if (ferror(fp_in)) { re = false; break; } if (len == 0) break; if(gzwrite(out, buf, (unsigned)len) != len) { re = false; } } gzclose(out); fclose(fp_in); return re;}bool UnCompress(const char * DestName,const char *SrcName){ if (!DestName || !SrcName) { __android_log_print(ANDROID_LOG_DEBUG, "Tag", "Parameters error: DestName=%p, SrcName=%p\n", DestName, SrcName); return false; } FILE * fp_out = NULL; bool re = true; gzFile in; unsigned int len = 0; char buf[BUFFER_SIZE]; in = gzopen(SrcName,"rb"); if (in == NULL) { __android_log_print(ANDROID_LOG_DEBUG, "Tag", "Open Src file error: %s", SrcName); return false; } if (NULL == (fp_out = fopen(DestName,"wb"))) { gzclose(in); __android_log_print(ANDROID_LOG_DEBUG, "Tag", "Open Dest file error: %s(%s)", DestName, strerror(errno)); return false; } for (;;) { len = gzread(in,buf,sizeof(buf)); if(len < 0) { re = false; break; } if(len == 0) break; if(fwrite(buf,1,(unsigned)len,fp_out) != len) { re = false; break; } } fclose(fp_out); gzclose(in); return re;}#ifdef UNZIP_TESTint main(void){ bool re = Compress("./a.so", "./b.so"); if (!re) { printf("Compress error!\n"); } else { printf("Compress success!\n"); } re = UnCompress("./b.so", "./a.so"); if (!re) { printf("Uncompress error!\n"); } else { printf("Uncompress success!\n"); } return 0;}#endifconst char originLibName[] = "/data/data/com.android.xxx/lib/liba.so";const char dstLibName[] = "/data/data/com.android.xxx/lib/libb.so";jboolean UnzipSOFile(JNIEnv*) {__android_log_print(ANDROID_LOG_DEBUG, "Tag", "UnzipSOfile!\n"); bool re = UnCompress(dstLibName, originLibName); if (!re) { __android_log_print(ANDROID_LOG_DEBUG, "Tag", "Unzip dynamic library error."); } return static_cast<jboolean>(re);}void LoadLibCompleted(JNIEnv*) { remove(dstLibName);}const char kClassName[] = "com/android/xxx/Unzip";const JNINativeMethod kJniMethods[] = { { "nativeUnzipSOFile", "()Z", reinterpret_cast<void*>(UnzipSOFile) }, { "nativeLoadLibCompleted", "()V", reinterpret_cast<void*>(LoadLibCompleted) }};} // namespacevoid RegisterZLoader(JNIEnv* env) { jclass clazz = env->FindClass(kClassName); int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods));}} // namespace android
jni_entry_point.cpp
#include <jni.h>#include <stdio.h>#include <android/log.h> namespace android { void RegisterZLoader(JNIEnv* env);} // namespace androidJNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { __android_log_print(ANDROID_LOG_DEBUG, "Tag", "Unzip -> JNI_OnLoad\n"); JNIEnv* env = 0; jint ret = vm->AttachCurrentThread(&env, 0); android::RegisterZLoader(env); return JNI_VERSION_1_4;}Android.mk
LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)TARGET_BUILD_APPS := falseLOCAL_ARM_MODE := arm LOCAL_MODULE := libUnzipLOCAL_MODULE_TAGS := optionalLOCAL_SRC_FILES:= \ jni_entry_point.cpp \ Unzip.cppLOCAL_C_INCLUDES:= \ $(SYSROOT_INC)/usr/include \ $(PWD)/ndk/sources/cxx-stl/stlport/stlport \ $(PWD)/external/chromium_org \ $(PWD)/external/chromium_org/third_party/zlib LOCAL_C_INCLUDES_Release := \ $(LOCAL_C_INCLUDES)LOCAL_C_INCLUDES_Debug := \ $(LOCAL_C_INCLUDES)LOCAL_CFLAGS += -DAVOID_TABLESLOCAL_CPPFLAGS_Release := \ -fPIC \MY_CFLAGS_Release := \ -fPIC \LOCAL_LDFLAGS_Release := \ -fPIC \LOCAL_SHARED_LIBRARIES := libz liblogLOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))LOCAL_LDFLAGS := $(LOCAL_LDFLAGS_$(GYP_CONFIGURATION))include $(BUILD_SHARED_LIBRARY)
注:
1.Android JNI 使用的数据结构JNINativeMethod
typedef struct {
const char* name; // Java中函数的名字
const char* signature; // 描述了函数的参数和返回值的字符串
void* fnPtr; // C函数指针
} JNINativeMethod;
http://hi.baidu.com/leicejbgnndjrze/item/b87a4895e06a6c1c924f41f4
第二个参数
"()" 中的字符表示参数,后面的则代表返回值。例如"()V" 就表示void Func();
"(II)V" 表示 void Func(int, int);
在编译chromium(android4.4)时产生好多jni目录,里面有很多这样的例子
out/target/product/generic/obj/GYP/shared_intermediates/android_view/jni/
具体的每一个字符的对应关系如下
字符 Java类型 C类型
V void void
Z jboolean boolean
I jint int
J jlong long
D jdouble double
F jfloat float
B jbyte byte
C jchar char
S jshort short
数组则以"["开始,用两个字符表示
[I jintArray int[]
[F jfloatArray float[]
[B jbyteArray byte[]
[C jcharArray char[]
[S jshortArray short[]
[D jdoubleArray double[]
[J jlongArray long[]
[Z jbooleanArray boolean[]
上面的都是基本类型。如果Java函数的参数是class,则以"L"开头,以";"结尾中间是用"/" 隔开的包及类名。而其对应的C函数名的参数则为jobject. 一个例外是String类,其对应的类为jstring
Ljava/lang/String; String jstring
Ljava/net/Socket; Socket jobject
如果JAVA函数位于一个嵌入类,则用$作为类名间的分隔符。
例如 "(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z"
2. native log re-direct logcat
使用android/log.h, 提供了4个函数
int __android_log_write(int prio, const char *tag, const char *text);
int __android_log_print(int prio, const char *tag, const char *fmt, ...) ;
int __android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap);
void __android_log_assert(const char *cond, const char *tag, const char *fmt, ...) ;
其中参数prio的值有:
typedef enum android_LogPriority {
ANDROID_LOG_UNKNOWN = 0,
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority;
- android ndk 生成so
- Android NDK生成so文件
- android NDK入门实例,生成.so文件
- android — NDK生成so文件
- android ndk 单C源文件 生成SO
- Android NDK 生成、调用so文件
- android 使用 ndk生成.so文件
- Android--ndk编译生成.so文件
- android — NDK生成so文件
- android — NDK生成so文件
- android — NDK生成so文件
- androidのNDK生成so文件
- android — NDK生成so文件
- android — NDK生成so文件
- Android NDK开发生成.so/.a库
- android ndk jni so库生成
- android--使用NDK-build生成so
- android ndk开发编译生成so文件
- Unity3D调用Android接口
- 【Cocoa】cocoa UI 常用算法
- 微软谷歌面试100题之调整数组顺序使奇数位于偶数前面
- XMPP协议实现原理介绍
- loadrunner自带例子r打不开IE
- android ndk 生成so
- C++ Primer Plus的string类的简单实现
- c++获取程序路径
- Linux删除文件夹命令
- vim bundle configuration
- cocos2dx 常用函数和宏定义
- c# asp.net 修改webconfig文件 配置
- 创建二叉树 树的深度搜索 广度搜索
- JVM调优