之所以摒弃NDK,是因为NDK编译出来的so太大,而且导出表总有一些没用的符号。而且手动编译的话,可以得到编译过程中间的.i和.s文件,可以删除一些没用的汇编代码。
现在代码列出来:
我的NDK C的代码如下,main.c:
[html] view plain copy
#include <stdio.h>
#include <string.h>
#include <jni.h>
#ifndef __ANDROID_LOGCAT_H__
#define __ANDROID_LOGCAT_H__
#define TEST_DEBUG 1
#ifdef TEST_DEBUG
#include <android/log.h>
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__)
#else
#define LOGI(...) {}
#define LOGD(...) {}
#define LOGW(...) {}
#define LOGE(...) {}
#define LOGF(...) {}
#endif
#endif
#define LOG_TAG "ss"
int encrypt() {
int i = 0;
char plaintext[128] = "abcdefg";
LOGI("in encrypt!");
return i;
}
JNIEXPORT jint Java_com_ss_jni_JNIUtil_nativec(JNIEnv *env, jclass thizz) {
encrypt();
return 1;
}
下面是Makefile文件的写法:
[html] view plain copy
NDK_ROOT=D:eclipse-androidandroid-ndk-r9d
TOOLCHAINS_ROOT=$(NDK_ROOT) oolchainsarm-linux-androideabi-4.6prebuiltwindows
TOOLCHAINS_PREFIX=$(TOOLCHAINS_ROOT)inarm-linux-androideabi
TOOLCHAINS_INCLUDE=$(TOOLCHAINS_ROOT)libgccarm-linux-androideabi4.6include-fixed
PLATFORM_ROOT=$(NDK_ROOT)platformsandroid-19arch-arm
PLATFORM_INCLUDE=$(PLATFORM_ROOT)usrinclude
PLATFORM_LIB=$(PLATFORM_ROOT)usrlib
CC := $(TOOLCHAINS_PREFIX)-gcc
FLAGS=-I$(TOOLCHAINS_INCLUDE)
-I$(PLATFORM_INCLUDE)
-L$(PLATFORM_LIB)
-fPIC
-shared
-llog
MODULE_NAME=hello
CFLAGS = -Wall -g
LDFLAGS = -llog -shared
SRC =hello.c
EXE =librusteze.so
all:
$(CC) -E $(MODULE_NAME).c $(FLAGS) -o $(MODULE_NAME).i
$(CC) -S $(MODULE_NAME).i $(FLAGS) -o $(MODULE_NAME).s
$(CC) -c $(MODULE_NAME).s $(FLAGS) -o $(MODULE_NAME).o
$(CC) $(MODULE_NAME).o $(FLAGS) -o lib$(MODULE_NAME).so
$(TOOLCHAINS_PREFIX)-strip lib$(MODULE_NAME).so
clean:
$(RM) $(MODULE_NAME).i $(MODULE_NAME).s $(MODULE_NAME).o $(EXE)
可以看到首先gcc -E预编译
接下来gcc -S 编译
gcc -c汇编
strip隐藏符号和函数名字
在Windows平台,CMD命令行执行mingw32-make。(前提是装了MinGW,并且配置了环境变量)
[html] view plain copy
D:eclipse-androidandroid-ndk-r9d oolchainsarm-linux-androideabi-4.6prebuiltwindowsinarm-linux-androideabi-gcc -E main.c -ID:eclipse-androidandroid-ndk-r9d oolchainsarm-linux-androideabi-4.6prebuiltwindowslibgccarm-linux-androideabi4.6include-fixed -ID:eclipse-androidandroid-ndk-r9dplatformsandroid-19arch-armusrinclude -LD:eclipse-androidandroid-ndk-r9dplatformsandroid-19arch-armusrlib -fPIC -shared -llog -o main.i
D:eclipse-androidandroid-ndk-r9d oolchainsarm-linux-androideabi-4.6prebuiltwindowsinarm-linux-androideabi-gcc -S main.i -ID:eclipse-androidandroid-ndk-r9d oolchainsarm-linux-androideabi-4.6prebuiltwindowslibgccarm-linux-androideabi4.6include-fixed -ID:eclipse-androidandroid-ndk-r9dplatformsandroid-19arch-armusrinclude -LD:eclipse-androidandroid-ndk-r9dplatformsandroid-19arch-armusrlib -fPIC -shared -llog -o main.s
D:eclipse-androidandroid-ndk-r9d oolchainsarm-linux-androideabi-4.6prebuiltwindowsinarm-linux-androideabi-gcc -c main.s -ID:eclipse-androidandroid-ndk-r9d oolchainsarm-linux-androideabi-4.6prebuiltwindowslibgccarm-linux-androideabi4.6include-fixed -ID:eclipse-androidandroid-ndk-r9dplatformsandroid-19arch-armusrinclude -LD:eclipse-androidandroid-ndk-r9dplatformsandroid-19arch-armusrlib -fPIC -shared -llog -o main.o
D:eclipse-androidandroid-ndk-r9d oolchainsarm-linux-androideabi-4.6prebuiltwindowsinarm-linux-androideabi-gcc main.o -ID:eclipse-androidandroid-ndk-r9d oolchainsarm-linux-androideabi-4.6prebuiltwindowslibgccarm-linux-androideabi4.6include-fixed -ID:eclipse-androidandroid-ndk-r9dplatformsandroid-19arch-armusrinclude -LD:eclipse-androidandroid-ndk-r9dplatformsandroid-19arch-armusrlib -fPIC -shared -llog -o librusteze.so
D:eclipse-androidandroid-ndk-r9d oolchainsarm-linux-androideabi-4.6prebuiltwindowsinarm-linux-androideabi-strip librusteze.so
编译成功:
得到librusteze.so
新建一个Android工程testso:
[html] view plain copy
public class JNIUtil {
static {
System.loadLibrary("rusteze");
}
public static native int nativec();
}
在MainActivity中调用JNIUtil.nativec();
[html] view plain copy
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
JNIUtil.nativec();
}
}
可以看到logcat中打印出来的日志。
可以达到缩小so的目的,还有导出表里也没有那些奇怪的导出符号了。
见下图:
但是导入表也没有了,见下图:
android工程代码在github上点击打开链接