1.编写并生成Android下可用的动态库
(1)编写动态库源程序文件
    这里以my_add.c为例。首先进入/home/android/development/,该目录下创建文件夹lib_test,更爱该目录的权限后进入该目录。依次执行

# 
     cd /home/android/development 
    
 
         
    # 
     mkdir lib_test 
    
 
         
    # 
     chmod 777 ./lib_test 
    
 
         
    # 
     cd ./lib_test



    在lib_test下创建my_add.c源文件,如下。


/* 
    
my_add.c
 
    */ 
    
#include  
    < 
    stdio.h 
    > 
    
 
    int 
     add( 
    int 
     x,  
    int 
     y)
{    
     
    int 
     sum  
    = 
     x  
    + 
     y;
    printf( 
    " 
    The sum of %d and %d is %d\n 
    " 
    , x, y, sum);
     
    return 
     sum;
}

该程序计算两个整形变量的和并返回该值,同时打印求和信息。



(2)编写Android.mk文件


  在lib_test目录下创建Android.mk文件,内容如下


LOCAL_PATH: 
    = 
    $(call my 
    - 
    dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES: 
    = 
     my_add.c
LOCAL_MODULE: 
    = 
    libmy_add
LOCAL_PRELINK_MODULE : 
    = 
     false
include $(BUILD_SHARED_LIBRARY)



(3)编译动态库


    进入lib_test目录,用mm命令编译动态库。


    # cd /home/android/development/lib_test


    # mm


    编译完成之后生成的动态库文件明为$(LOCAL_MODULE).so,即libmy_add.so。该动态库位于/home/android/out/target/product/generic/system/lib目录下。



2.调用动态库


(1)编写调用动态库的源程序


    在删除之前在lib_test目录下的创建的my_add.c和Android.mk文件,并在该目录下创建libtest.c文件以及my_add.h文件,内容如下:


/* 
    
libtest.c
 
    */ 
    
#include  
    < 
    stdio.h 
    > 
    
#include  
    " 
    my_add.h 
    " 
    

 
    int 
     main()
{
    add( 
    3 
    , 
    4 
    );
    printf( 
    " 
    Done\n 
    " 
    );
     
    return 
      
    0 
    ;
}



my_add.h头文件:


/* 
    
my_add.h
 
    */ 
    
 
    int 
     add( 
    int 
     x,  
    int 
     y);



(2)编写Android.mk文件


    在lib_test目录下创建Android.mk文件,内容如下。


LOCAL_PATH: 
    = 
    $(call my 
    - 
    dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES: 
    = 
    libtest.c
LOCAL_MODULE: 
    = 
    lib_test
LOCAL_SHARED_LIBRARIES: 
    = 
    libmy_add



include $(BUILD_EXECUTABLE)


注:LOCAL_SHARED_LIBRARIES指明要调用的动态库文件,这里动态库文件为libmy_add.so,


位于/home/android/out/target/product/generic/lib目录下,编译时会自动在这个目录

下寻找该动态库文件。



(3)编译


    进入lib_test目录,使用mm命令进行编译。


    # cd /home/android/development/lib_test


    # mm


    生成的可执行文件lib_test文件位于/home/android/out/target/product/generic/system/bin目录下。



3.在Android模拟器中使用


(1)启动模拟器


(2)运行程序


    等待模拟器初始化完成后,将lib_test文件push进模拟器,并将libmy_add.so文件push至模拟器的system/lib目录下。


    由于模拟器下/system/目录为制度目录,需修改权限,使用adb remount 命令。依次执行:    


    #adb remount


    # adb push /home/android/out/target/product/generic/system/lib/libmy_add.so /system/lib


    # adb push /home/android/out/target/product/generic/system/bin/lib_test /data


    执行push命令之后登录模拟器,在模拟器终端下调用lib_test执行。


    # adb shell


    #/data/lib_test



4.隐藏动态库函数细节


    可通过选项-fvisibility=hidden将动态库中不必要暴露的函数和全局变量隐藏起来。从而在调用动态库的时候,只有不被隐藏(开放)的函数可以调用,其他函数和变量这部能被调用(引用)。在Android.mk文件中LOCAL_CFLAG中加入该选项即可,及LOCAL_CFLAG += -fvisibility=hidden。而要开放的函数前只需加上__attribute__ ((visibility ("default")))限定。


    例如生成通过以下mylib.c生成动态库libmylib.so,可编写Android.mk文件为:


# 
    Android.mk file 
    
 
    LOCAL_PATH: 
    = 
    $(call my 
    - 
    dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES: 
    = 
    \
                  mylib.c
LOCAL_MODULE: 
    = 
    libmylib
LOCAL_CFLAGS  
    +=- 
    fvisibility 
    = 
    hidden
LOCAL_PRELINK_MODULE : 
    = 
     false
include $(BUILD_SHARED_LIBRARY)



/* 
    
mylib.c
 
    */ 
    
#include  
    < 
    stdio.h 
    > 
    

__attribute__ ((visibility ( 
    " 
    default 
    " 
    )))   
    int 
     add( 
    int 
     x,  
    int 
     y)
{
     
    int 
     sum  
    = 
     x  
    + 
     y;
    printf( 
    " 
    %d add %d is %d\n 
    " 
    , x, y, sum);
     
    return 
     sum;
}


 
    int 
     sub( 
    int 
     x,  
    int 
     y)
{
     
    int 
     sub  
    = 
     x  
    - 
     y;

    printf( 
    " 
    %d sub %d is %d\n 
    " 
    , x, y, sub);
     
    return 
     sub;
}

 
    int 
     mul( 
    int 
     x,  
    int 
     y)
{
     
    int 
     mul  
    = 
     x 
    * 
    y;

    printf( 
    " 
    %d multiply %d is %d\n 
    " 
    , x, y, mul);

     
    return 
     mul;
}



    这样通过mm命令编译生成的libmylib.so中只有函数int add(int x, int y)是可以被调用的,而int sub(int x, int y)和int mul(int x, int y)则不能被调用。如过源文件调用动态库中的sub(或mul)函数,编译该文件是会出现无法找到sub函数的错误。