layout: post
title: 對比Linux和Windows關(guān)于動態(tài)鏈的使用
categories: Windows
description: 對比linux和windows關(guān)于動態(tài)鏈的使用
keywords: dynamic library
url: https://lichao890427.github.io/ https://github.com/lichao890427/
Windows情況
??Windows上存在2種方式實(shí)現(xiàn)b.dll/b.exe使用a.dll中的函數(shù)void func()
- 編譯時確定趣避,使windows在加載和解析(b.dll/b.exe)導(dǎo)入表的時候自動加載a.dll读规,分2步
- 添加函數(shù)聲明:void func();(extern 及 __declspec(dllimport)可選)
- 引入導(dǎo)入lib:#pragma comment(lib, "a.lib") ----注意導(dǎo)入lib和靜態(tài)lib的區(qū)別
- 運(yùn)行時獲取恰起,這種方式可以在(b.dll/b.exe)執(zhí)行的任意時刻加載a.dll并調(diào)用函數(shù)赘娄,也分2步
- 將模塊加載到內(nèi)存或獲取已有模塊 HMODULE hmod = LoadLibrary("a.dll",.....)/GetModuleHandle("a.dll")
- 獲取函數(shù)并執(zhí)行
typedef void (*F)();F func=(F)GetProcAddress(hmod,"func");func();
Android情況
??Android/Linux上,并不把特定函數(shù)歸于某個模塊故黑,它存在一個模塊鏈儿咱,從第一個so開始遍歷,直到找到函數(shù)為止场晶,同樣分2種方式實(shí)現(xiàn)b/b.so使用a.so中的函數(shù)void func() 下面的方法都是采用ndk
- 編譯時確定——這個是我要重點(diǎn)說的混埠,因?yàn)榫W(wǎng)上資料較少,分系統(tǒng)函數(shù)和用戶函數(shù)
- 用戶函數(shù)——自己從網(wǎng)上down的诗轻,或自己寫的導(dǎo)出函數(shù)的so
Android.mk中編寫配置
- 用戶函數(shù)——自己從網(wǎng)上down的诗轻,或自己寫的導(dǎo)出函數(shù)的so
LOCAL_SRC_FILES := a.cpp
LOCAL_MODULE := a
LOCAL_MODULE_FILENAME := a
include $(BUILD_SHARED_LIBRARY)
LOCAL_SRC_FILES := b.cpp
LOCAL_MODULE := b
LOCAL_MODULE_FILENAME := b
LOCAL_SHARED_LIBRARIES := liba #導(dǎo)入a的函數(shù)
include $(BUILD_SHARED_LIBRARY)
這樣就可以讓b去用a的導(dǎo)出函數(shù)岔冀,b.cpp中仍然要包含a的函數(shù)聲明
- 系統(tǒng)函數(shù)——ndk自帶的庫函數(shù),包括stl概耻,log等
Android.mk中編寫配置
LOCAL_SRC_FILES := b.cpp
LOCAL_MODULE := b
LOCAL_MODULE_FILENAME := b
LOCAL_LDLIBS := -llog #導(dǎo)入liblog.so中的函數(shù)
include $(BUILD_SHARED_LIBRARY)
再包含android/log.h即可
系統(tǒng)自帶的庫參見%NDK%\build\core\build-binary.mk
system_libs := \
android \
c \
dl \
jnigraphics \
log \
m \
m_hard \
stdc++ \
z \
EGL \
GLESv1_CM \
GLESv2 \
GLESv3 \
OpenSLES \
OpenMAXAL \
bcc \
bcinfo \
cutils \
gui \
RScpp \
RScpp_static \
RS \
ui \
utils \
mediandk \
atomic
- 動態(tài)加載使套,這和windows類似,分2步
int hmod = dlopen("/system/lib/a.so",
typedef void (*F)();F func=(F)dlsym(hmod,"func");func();