使用android ndk r8 编译nativc C,生成动态库。并连接使用
#今天我讲解的是如何使用Android.mk文件加上android ndk来编译一个可以加载动态库的命令。 我用到的实例是math。目的是把double.c trip.c编译成double.so 再编译main.c并连接到double.so 其中要用到三个文件,分别是double.c trip.c main.c 各文件的内容如下: /* main.c */ #include<stdio.h> #include<math.h> int main() { extern double dou(); extern double trip(); double x,y,z; puts("Enter a number please:"); scanf("%lf",&x); y=dou(x); z=trip(x); printf("doub of the number is: %lf\n",y); printf("trip of the number is: %lf\n",z); printf("the sqrt of the trip is %lf\n",sqrt(z)); return 0; } ########### /*double.c */ #include<stdio.h> double dou( double n) { return n*n; } ######### /*trip.c */ #include<stdio.h> double trip(double n) { return n*n*n; } ###### 下面的文件是最重要的:Android.mk # build the math module for android LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) #声名模块的开始 LOCAL_MODULE := double #生成的模块名称是double LOCAL_SRC_FILES := double.c trip.c #编译要用以的源代码文件 LOCAL_EXPORT_LDLIBS:= -llog #连接要用到的注册库(liblog.so),为下面的编译做准备 include $(BUILD_SHARED_LIBRARY) #编译生成动态的库文件lib$(LOCAL_MODULE).so
include $(CLEAR_VARS) LOCAL_MODULE :=math LOCAL_SRC_FILES :=main.c LOCAL_SHARED_LIBRARIES :=double m #声名需要连接的库文件分别是,上面编译的libdouble.so libm.so include $(BUILD_EXECUTABLE) #生成可以执行的文件$(LOCAL_MODULE) ######################## 现在对编译的工具的位置说明一下: 我把编译工具放置在/home/sn/android-ndk-r8目录里面。 编译源代码的目录是/home/sn/code/learning-c 真正的源代码放置位置是/home/sn/code/learning-c/jni 编译的时候,主要在jni的上层目录进行,即是learning-c目录, 我在终端的目录显示为如下: root@sn-workshop:/home/sn/code/learning-c# 我把以上的目录简写为$(PROJECT), { 即为我定义为有如下的规则PROJECT=/home/sn/code/learning-c 所以我的编译命令就是如下所示: $(PROJECT) http://www.cnblogs.com/android-ndk-r8/ndk-build 编译器运行的时候得到如下信息输出: Compile thumb : double <= double.c Compile thumb : double <= trip.c V - SharedLibrary : libdouble.so Install : libdouble.so => libs/armeabi/libdouble.so Compile thumb : math <= main.c Executable : math Install : math => libs/armeabi/math -------------------------- 上面显示的信息如图所示: #加入图片 能显示以上的信息,证明已经编译成功了。 下面用cd命令进入生成math和libdouble.so文件目录,命令如下: $(PROJECT) cd ./libs/armeabi 查看当前目录的文件是否存在: $(PROJECT)/libs/armeabi#ls #显示 libdouble.so math ----------------- 现在使用arm-linux-androideabi-readelf命令查看一下,math命令需要哪些动态库文件(*.so)文件。 其中这个arm-linux-androideabi-readelf是你从android ndk r7(r8)的源代码程序中,提取出来的单独的toolchain, 并把得到的toolchain加入到环境中去。 真正的命令如下所示: $(PROJECT)libs/armeabi#arm-linux-androideabi-readelf -d math #其中的选项"-d",目的是显示加载的动态库 显示的内容如下: ------------------------------------- Dynamic section at offset 0x2490 contains 26 entries: Tag Type Name/Value 0x00000001 (NEEDED) Shared library: [libdouble.so] 0x00000001 (NEEDED) Shared library: [liblog.so] 0x00000001 (NEEDED) Shared library: [libstdc++.so] 0x00000001 (NEEDED) Shared library: [libm.so] 0x00000001 (NEEDED) Shared library: [libc.so] 0x00000001 (NEEDED) Shared library: [libdl.so] 0x00000020 (PREINIT_ARRAY) 0X12470 0X00000021 (PREINIT_ARRARYSZ) 0x8 --------------------- 下面是实际的操作: 下面用adb push命令把生成的两个文件push到手机目录 ,前提是你的linux系统已经正确配置adb, 还有你的手机已经root 要用到的命令如下: adb push math /system/math #把生成的文件push到手机的/system目录下面去 adb push libdouble.so /system/lib/libdouble.so #把生成的libdouble.so文件push到/system/lib目录去, 因为这个目录是动态库文件放置的地方。 #注意当没有把libdouble.so文件复制到/system/lib目录的时候会出现如下的错误: Link_image[1962]: 726 could not load needed library 'libdouble.so' for './math' (Load_library[1104]: Library 'libdouble.so' not found)CANNOT LINK EXECTABLE 继续输入如下的命令:(‘#’后面是解释词) adb shell #进入手机的调试终端 #如果你的手机是从内核得到权限的,会显示这个提示符# $ #如果你的手机是没有从内核得到权限的,就会显示这个提示符, 当出现$提示符的时候,再输入su,再在手机的屏幕上面按确定就行了。 . 再用如下的命令: #cd /system #进入/system目录, # ls math #查看当前目录是否有math文件, #./math #运行math程序, ` Enter a number please 4 double of the numbe is : 16.000000 trip of the numbe is :64.000000 the sqrt of the trip is 8.000000 # #程序运行完成后,返回命令行的终端模式。 #exit #退出调试终端。 以上就是全部了。 今天的教程到此为止。
|
请发表评论