原文网址: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库的二种方法(含示例) -- 不错相关推荐

  1. Android下玩JNI的新老三种姿势

    请尊重原创,转载请注明出处:http://blog.csdn.net/mabeijianxi/article/details/68525164 (本文已在 hongyang 微信公众号发布) 说明:本 ...

  2. Android Studio导入第三方库的三种方法

    今天在项目中使用一个图片选择器的第三方框架--GalleryFinal,想要导入源码,以便于修改,于是上完查找了一下方法,想到之前用到过其他导入第三方库的方法,现在做个小总结,以防忘记. Androi ...

  3. php 扩展库curl下载,PHP添加CURL扩展库的二种方法

    说明: 本次编译只是单独编译php的扩展库,然后将编译好的php扩展库加到现在运行的php中,不对现在运行的php重新编译,对现在运行的php没有任何影响. 有两种方法可以实现这一操作,下面分别介绍. ...

  4. Win10系统下编译运行汇编程序的3种方法

    一:基于DOSBox0.74-3 **写在前面:**本文所指的"书"或"教材"等如无特殊说明均指<汇编语言第4版王爽著> **1. 软件下载安装:* ...

  5. php 加载curl 扩展,PHP添加CURL扩展库的二种方法

    wget http://curl.haxx.se/download/curl-7.19.6.tar.gz tar -zxvf curl-7.19.6.tar.gz cd curl-7.19.6 ./c ...

  6. Android下查看共享库依赖项

    Android下查看共享库依赖项 [时间:2017-02] [状态:Open] [关键词:android,共享库依赖项,so,ndk,objdump,readelf] 起因 近期在处理Android下 ...

  7. 四种环境下编译nanomsg库

    VS2013编译生成nanomsg库文件 因为工作中用到了nanomsg,又需要编译成库来使用,发现网上资料很少,所以做此记录. 编译准备,CMake工具软件和下载好的nanomsg源码包.我的是CM ...

  8. windows下编译skia库

    windows下编译skia库 环境需求: 1.安装python2.7.x: python3系列可能又某些库不支持,所以推荐使用python2.7.15(最新). 如何检查是否安装python: 1. ...

  9. C++ Boost库:windows下编译Boost库

    文章目录 1. 需要编译的boost库 2. 编译步骤 3. 库命名规则 4. VS配置库目录 C++ Boost库:简介和第一个示例程序 C++ Boost库:数值转换 lexical_cast C ...

最新文章

  1. Mysql 共享锁(lock in share mode),排他锁(for update)
  2. win系统下Cygwin 安装和sftp环境搭建
  3. python项目归纳总结-python项目总结
  4. C: Answers to “The C programming language, Edition 2”
  5. 一起学nRF51xx 0 - 环境搭建
  6. java单分支结构,java基础语法分支结构
  7. 趣谈Linux操作系统01:概述
  8. python与txt文件查找,在Python中搜索TXT文件
  9. MapGuide安装
  10. html取消波浪线,PPT文字下划波浪线如何去掉?
  11. tof摄像头手势识别_全面解析深度摄像头(TOF Camera)的原理
  12. Java小白-9.Java多线程
  13. 在日本做科研工作是怎样的体验?
  14. Salvage Robot[agc-004E]
  15. python字符串格式时间转化为时间戳
  16. CIKM 2021 | DISENKGAT:知识图谱解耦表征学习
  17. 解义盼:比特大陆大规模裁员,资本的寒冬到了?
  18. R实战| 雷达图(Radar Chart)
  19. 计算机输入知识竞赛简讯,计算机学院积极参与“不忘初心之感知我矿大”知识竞赛...
  20. 可可西里-昨夜,真实让我感动!

热门文章

  1. AddressSanitizer+cmake
  2. codecheck_use_record
  3. WMI Series :事件预订和处理
  4. 使用DataGrid动态绑定DropDownList
  5. 怎样把DataGrid存放在ViewState中的无用数据卡掉
  6. VirtualBox虚拟机安装RedHat7.3编译Linux0.01内核
  7. 用python3实现指定目录下文件sha256及文件大小统计
  8. C++11中override的使用
  9. matlab常遇小问题汇总
  10. 【linux】SELinux工具:semanage的安装和使用