dl1.c 是主函数 shell
//dl1.c #include<stdio.h> #include<dlfcn.h> #include"dl1.h" int main(){ scanf("%d%d", &a, &b); p = dlopen("./dl2.so", RTLD_NOW); func_max = dlsym(p, "max"); printf("%d 与 %d相比,%d为大数。\n", a, b, (*func_max)(a, b)); dlclose(p); }d1l.h
//dl1.h int a, b; void *p; int (*func_max)(int, int);dl2.c 是比较函数,用于编译成so文件
//dl2.c #include<stdio.h> int max(int x, int y){ return x>y?x:y; }
编译 函数
gcc dl2.c -o dl2.so -shared -fPIC
gcc dl1.c -o dl1 -ldl
-ldl选项,表示生成的对象模块须要使用共享库 字体
(1)dlopen()
第一个参数:指定共享库的名称,将会在下面位置查找指定的共享库.
-环境变量LD_LIBRARY_PATH列出的用分号间隔的全部目录.
-文件/etc/ld.so.cache中找到的库的列表,用ldconfig维护.
-目录usr/lib.
-目录/lib.
-当前目录. spa
第二个参数:指定如何打开共享库。
-RTLD_NOW:将共享库中的全部函数加载到内存
-RTLD_LAZY:会推后共享库中的函数的加载操做,直到调用dlsym()时方加载某函数 code
(2)dlsym()
调用dlsym时,利用dlopen()返回的共享库的phandle以及函数名称做为参数,返回要加载函数的入口地址。 对象
(3)dlerror()
该函数用于检查调用共享库的相关函数出现的错误。 内存
(4)dlclose()
该函数用于关闭动态库。 get
编写Android.mk 源码
LOCAL_PATH:= $(call my-dir) io
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
dl2.c
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := true
#LOCAL_CFLAGS=-fPIC
LOCAL_MODULE:= libdl2
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
dl1.c
#LOCAL_CFLAGS:=-lmax
#LOCAL_LDFLAGS:= -Lout/target/product/generic/obj/lib
LOCAL_MODULE_TAGS := optional
LOCAL_SHARED_LIBRARIES := \
libdl
#LOCAL_CFLAGS=-ldl
LOCAL_MODULE:= dl1
include $(BUILD_EXECUTABLE)
libdl.so是系统自动生成
上一次之因此失败,缘由彷佛是使用了红色字体的那一句,由于我将其更换为蓝色字体的那一句,问题就解决了。看来这样写在连接时才能正确找到libdl.so,而包含该.so文件是使用dlopen函数的保证。
将这三个文件放在Android源码目录下的development目录下的dl文件夹中(dl文件夹是新建的),而后在终端中使用root权限进入到Android源码目录下,执行 make dl1 ,make dl2。编译出dl2.so和dl1
使用如下命令将它们放入Android模拟器,注意要先启动emulator
adb push Android源码目录/out/target/product/generic/system/lib/dl2.so /data
adb push Android源码目录/out/target/product/generic/system/bin/dl1 /data
进入data文件夹执行
adb shell
# cd data
# ./dl1
87 9(这里随便输入两个数)
dlopen ok!
87与9相比,87为大数。