【转】Android下编译jni库的二种方法(含示例)
原文网址:http://blog.sina.com.cn/s/blog_3e3fcadd01011384.html
总结如下:两种方法是:
1)使用Android源码中的Make系统
2)使用NDK(从NDK r5开始)
---------------------------------
源码要求: 如果Android工程的顶层目录为my_android_project_name:
1) my_android_project_name/jni/Android.mk文件的示例内容如下(以生成libjni_mouse.so的C代码为例):
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := libjni_mouse
LOCAL_SRC_FILES := jni_mouse.c
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
LOCAL_SHARED_LIBRARIES := libcutils
include $(BUILD_SHARED_LIBRARY)
2)源文件的部分内容(仅供参考):
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <jni.h> // located in $JDK/include
#include <cutils/log.h> // for Android Make system: $Android_SRC/system/core/include/cutils/log.h
//#include <android/log.h> // for NDK compiler
#define LOG_DBG(tag,fmt,args...) __android_log_print(ANDROID_LOG_DEBUG,tag,fmt,##args)
#define LOG_ERR(tag,fmt,args...) __android_log_print(ANDROID_LOG_ERROR,tag,fmt,##args)
#ifdef ___DEBUG
#define DBG(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, ##args)
#else
#define DBG(fmt, args...)
#endif //___DEBUG
#define OUT(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
#define JNIREG_CLASS "com/my_organization/my_pkg/JniMouse"
static JNINativeMethod JniMouseMethods[] = {
{ "nativeOpenMouse", "()I", (void*) openMouse },
{ "nativeCloseMouse", "()V", (void*) closeMouse },
{ "nativeMoveCursor", "(II)V", (void*) moveCursor },
...
};
static int registerNativeMethods(JNIEnv* env, const char* className, JNINativeMethod* methods,
int numMethods)
{
jclass clazz;
// C++ way: clazz= env->FindClass(className);
clazz = (*env)->FindClass(env, className);
if (clazz == NULL) {
LOG_ERR(TAG, "Native registration error: unable to find class\n");
return JNI_FALSE;
}
// C++ way: if (env->RegisterNatives(clazz, methods, numMethods) < 0)
if ((*env)->RegisterNatives(env, clazz, methods, numMethods) < 0) {
LOG_ERR(TAG, "RegisterNatives failed\n");
return JNI_FALSE;
}
return JNI_TRUE;
}
static int registerNatives(JNIEnv* env)
{
if (!registerNativeMethods(env, JNIREG_CLASS, JniMouseMethods,
sizeof(JniMouseMethods) / sizeof(JniMouseMethods[0])))
return JNI_FALSE;
return JNI_TRUE;
}
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -1;
// this is for C++: if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOG_ERR(TAG, "ERROR: GetEnv failed\n");
goto bail;
}
assert(env != NULL);
if (!registerNatives(env)) {
LOG_ERR(TAG, "ERROR: jni_mouse native registration failed\n");
goto bail;
}
result = JNI_VERSION_1_4;
bail:
return result;
}
---------------------------------
编译过程具体如下:
1)使用Android源码中的Make系统:
$ cd $ANDROID_SRC # (e.g. /u_data/android/sourcecode/and22)
$ . build/envsetup.sh
# 这样就会生成许多shell工具,实际上是shell函数。
$ lunch MY_LUNCH_NUMBER # 如果你的项目需要用到PLATFORM相关的内容(共享库/java库等)
# 把Android工程的顶层目录符号链接(或者拷贝)到 $ANDROID_SRC/packages/apps,如
$ ln -fs /abs/path/to/my_android_project_name $ANDROID_SRC/packages/apps
$ mmm packages/apps/my_android_project_name
# 如果没有错误,就会生成以下文件(取决于你使用的PRODUCT名字):
# $ANDROID_SRC/out/target/product/$PRODUCT_NAME/system/lib/libjni_mouse.so
# 最后拷贝生成的库文件到Android工程的libs/armeabi/目录下:
$ mkdir -p $ANDROID_SRC/packages/apps/my_android_project_name/libs/armeabi
$ cp $ANDROID_SRC/out/target/product/$PRODUCT_NAME/system/lib/libjni_mouse.so \
$ANDROID_SRC/packages/apps/my_android_project_name/libs/armeabi
# 这样,在eclipse中正常编译/生成.apk文件时,就会把生成的jni库自动包含进.apk文件中,这可以使用unzip命令来验证:
# cp my.apk /tmp/tmp/my.zip; cd /tmp/tmp; unzip my.zip; ls -l lib/armeabi/lib*.*
2)使用NDK(from NDK r5)
从NDK r5开始,NDK正式作为独立的工具来编译jni的代码,但它往往缺少某些头文件,如<linux/uinput.h>。
0)准备环境变量,如:
$ export NDK=/u_data/android/sourcecode/android-ndk-r6b
$ export CC=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc
$ export STRIP=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-strip
$ export SYSROOT=$NDK/platforms/android-8/arch-arm # 要看你使用的目标Android的版本 :)
1) 对于缺少的头文件,可以借用PC上的x86下的同名文件,如:
cd $NDK/platforms/android-8/arch-arm/usr/include/linux
ln -fs ../../../../arch-x86/usr/include/linux/uinput.h .
2) 编译出可执行文件(如果有main函数),如:
$ $CC --sysroot=$SYSROOT -o my_jni_mouse_exe jni_mouse.c my_main_func.c
#注: '--sysroot=dir':Use dir as the logical root directory for headers and libraries.
3) 编译出共享库(如果没有main函数),如:
$ $CC --sysroot=$SYSROOT -fPIC -o jni_mouse.o -c jni_mouse.c # optional '-o ...'
$ $CC --sysroot=$SYSROOT -shared -o libjni_mouse.so jni_mouse.o
# 再strip一下,以便减少其大小(直接覆盖原来的库文件):
$ $STRIP libjni_mouse.so
4)(可选)链接如上刚生成的共享库:
$ $CC --sysroot=$SYSROOT -L. -ljni_mouse -o my_hello my_hello.c
<EOF>
【转】Android下编译jni库的二种方法(含示例)的更多相关文章
- 【转】Android下编译jni库的二种方法(含示例) -- 不错
原文网址:http://blog.sina.com.cn/s/blog_3e3fcadd01011384.html 总结如下:两种方法是:1)使用Android源码中的Make系统2)使用NDK(从N ...
- Android Studio导入第三方库的三种方法
叨叨在前 今天在项目中使用一个图片选择器的第三方框架——GalleryFinal,想要导入源码,以便于修改,于是上完查找了一下方法,想到之前用到过其他导入第三方库的方法,现在做个小总结,以防忘记. A ...
- 在Android源码下编译jni所需要知道的事~
以下只是自己的一些总结,欢迎讨论 通过NDK编译jni网上有很多例子,在这我只总结在Android源码下编译 1.android源码环境下编译so包,编出来的.so的包前面不会自动给添加lib,NDK ...
- 手把手图文并茂教你用Android Studio编译FFmpeg库并移植
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52661331 之前曾写过一篇&l ...
- android ndk-build 编译静态库libxx.a 以及Android studio openssl 静态库配置(cmake)
android ndk-build 编译静态库libxx.a 需求场景: 目前有安卓编码好的现在的openssl的两个.a,我们需要调用openssl的函数,并把功能再封装成.a; 这样使用时,在an ...
- Android下查看共享库依赖项
Android下查看共享库依赖项 [时间:2017-02] [状态:Open] [关键词:android,共享库依赖项,so,ndk,objdump,readelf] 起因 近期在处理Android下 ...
- 在Ubuntu下编译Assimp库
在Ubuntu下编译Assimp库 怎样在Ubuntu下编译Assimp库?这是我曾经编译成功后做的笔记,供參考. 1.去以下的站点去下载Assimp库: http://assimp.sourcefo ...
- NDK下编译JNI
NDK环境下编译JNI 下载demo.tar.gz然后解压 弄个套路 1.编辑build.sh设置好NDK目录 2.把cpp文件放到code下面 运行sh build.sh即可
- 痞子衡嵌入式:MCUXpresso IDE下设置代码编译优化等级的几种方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是MCUXpresso IDE下设置代码编译优化等级的几种方法. 最近公司芯片设计团队正在开发一款全新的基于 Cortex-M33 内核的 ...
随机推荐
- poj2723-Get Luffy Out
一道2-SAT问题,每对钥匙需要加一条边,每扇门上的对应的要用的钥匙加一条边. 其实求解2-SAT问题,关键在于找到不能同时成立的条件,例如在本题中,每对钥匙不能同时使用,每扇门上的钥匙不能同时不使用 ...
- MVC中使用EF(2):实现基本的CRUD功能
MVC中使用EF(2):实现基本的CRUD功能 By Tom Dykstra |July 30, 2013 Translated by litdwg Contoso University示例网站 ...
- c语言结构体4之结构体引用
struct mystruct{ char str[23];}; 1结构体变量不能整体引用 struct data m: printf("%s",m);//m是结构体变量 2 st ...
- Web 前端利器Emmet 的HTML用法总结
在tutsplus那里看到一篇文章介绍Emmet 的用法,形象的gif图片一目了然,本来想翻译过来的(虽然翻译用法倒不是很难),但搜索发现已经有国人翻译过了,遂直接拿来转载在这里. Emmet 简介 ...
- poj 1466 Girls and Boys(二分匹配之最大独立集)
Description In the second year of the university somebody started a study on the romantic relations ...
- hdu 1695 GCD(欧拉函数+容斥)
Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD( ...
- <Win32_6>程序员求爱的创意程序^_^
作为程序员,我们时常被外界误认为很闷.不浪漫.没创意……等等这一类人,这让我们实在有些感伤啊,我得为程序员呐喊一声: 我们也能可以欢快.浪漫.有创意…… 朋友,你向女生表白过吗? …… 这个问题有点儿 ...
- 基于drools创建自己的关系操作符
我们知道drools提供了12种关系操作符 但是有些时候这12种操作符依然不能满足我们的业务需求,我们可以扩展自己的操作符,下面是为某一航空公司做项目时扩展了操作符,在这分享下 首先,我们要实现的逻辑 ...
- javaweb 学习的好地方
http://www.cnblogs.com/xdp-gacl/p/3729033.html 强烈推荐这个哥们的学习笔记.太赞了.
- JS属性读写操作+if判断注意事项
js中不允许出现“ - ” 页面中改变文字大小-案例: <!doctype html> <html lang="en"> <head> < ...