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爲大數。