系列文章
- LIBDSM庫對多平臺、多方案支持的開發與探索 - 準備
- LIBDSM庫對多平臺、多方案支持的開發與探索 - Native Common
- LIBDSM庫對多平臺、多方案支持的開發與探索 - iOS
- LIBDSM庫對多平臺、多方案支持的開發與探索 - Android
- LIBDSM庫對多平臺、多方案支持的開發與探索 - Flutter
- LIBDSM庫對多平臺、多方案支持的開發與探索 - Unity
項目地址 - https://github.com/biezhihua/libdsm
架構
在一開始之初,我對此處的設計目標是個獨立模塊,但是由於對C++不夠熟悉,並且爲了能夠快速debug調試,之後將目標改爲了能夠與Android和iOS工程一起進行源碼編譯。
因此,雙端的架構,也有略微的不同之處。
雙端大部分都是一致的,也符合最大複用原則,只有編譯環境部分是不同的。
下面介紹一些基礎模塊:
- libdsm: 這部分是VLC維護的獨立模塊,具體可以參考準備的文章中,靜態庫構建的部分。該部分,提供了基礎的與SMB進行交互的API,比如:監聽、轉義、查詢等。
- wrapper: 由於本方案,本質上是對libdsm的二次封裝,這一部分是個
Dsm
類,裏面利用libdsm
提供的基礎API做了二次封裝和分發。 - json: 在方法結果中,有較多數據需要回傳給上層,此處採用JSON這種數據格式傳遞。爲了簡單化,在github上尋找了較爲知名json庫。
不同之處
Android
對於Android,目前主要用於組織C/C++代碼文件的方式是使用CMake。
通過編寫CMakeList.txt文件的方法組織源文件和引入的庫文件。
對於Wrapper部分的源文件,可以通過如下方式進行組織:
# 添加源碼子目錄
file(GLOB CPP_FILES
*.cpp
)
# 添加頭文件子目錄
file(GLOB H_FILES
nlohmann/*.h
*.h
)
# 設置源文件集合
set(SOURCE_FILES ${CPP_FILES})
# 設置庫
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
# 鏈接頭文件
target_include_directories(${PROJECT_NAME} PRIVATE
# 引入自有代碼頭文件
${CMAKE_CURRENT_SOURCE_DIR}
)
對於libdsm的靜態庫和頭文件,可以通過如下方式來組織:
# 設置根目錄
get_filename_component(CORE_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../ ABSOLUTE)
# 設置依賴庫(libdsm)的目錄
if (${CMAKE_SYSTEM_NAME} MATCHES "Android")
set(CORE_DISTRIBUTION_DIR ${CORE_ROOT_DIR}/distribution/android)
endif ()
# 鏈接頭文件
target_include_directories(${PROJECT_NAME} PRIVATE
# 引入 libdsm 頭文件
${CORE_DISTRIBUTION_DIR}/libdsm/include
)
# 鏈接 libdsm 模塊
if (${CMAKE_SYSTEM_NAME} MATCHES "Android")
add_library(lib_dsm STATIC IMPORTED)
set_target_properties(lib_dsm PROPERTIES IMPORTED_LOCATION ${CORE_DISTRIBUTION_DIR}/libdsm/lib/${ANDROID_ABI}/libdsm.a)
add_library(lib_iconv STATIC IMPORTED)
set_target_properties(lib_iconv PROPERTIES IMPORTED_LOCATION ${CORE_DISTRIBUTION_DIR}/libdsm/lib/${ANDROID_ABI}/libiconv.a)
add_library(lib_tasn1 STATIC IMPORTED)
set_target_properties(lib_tasn1 PROPERTIES IMPORTED_LOCATION ${CORE_DISTRIBUTION_DIR}/libdsm/lib/${ANDROID_ABI}/libtasn1.a)
add_library(lib_charset STATIC IMPORTED)
set_target_properties(lib_charset PROPERTIES IMPORTED_LOCATION ${CORE_DISTRIBUTION_DIR}/libdsm/lib/${ANDROID_ABI}/libcharset.a)
target_link_libraries(${PROJECT_NAME}
lib_dsm
lib_iconv
lib_tasn1
lib_charset
-landroid
-llog
)
endif ()
通過上面的組織後,打開Android工程,就能夠看到Native模塊被以源碼的方式,編譯到了工程之中。
iOS
對於XCODE而言,這相對方便很多。
- 在Build Phases中的Link Binary with Libraries中,將如下依賴項拖入其中:
distribution/ios/libdsm/lib/libcharset.a
distribution/ios/libdsm/lib/libdsm.a
distribution/ios/libdsm/lib/libiconv.a
distribution/ios/libdsm/lib/libtasn1.a
- 在Build Phases中的Compile Sources中,將如下源文件拖入其中:
libdsm_core/Dsm.cpp
- 在Build Phases中的Headers中,將如下頭文件拖入其中:
libdsm_core/nlohmann/json.h
libdsm_core/Log.h
libdsm_core/Dsm.h
distribution/ios/libdsm/include
實現
實現也很簡單,用C++語法構建了一個Dsm
類,主要API如下:
/**
* 開始發現SMB服務器
*/
int startDiscovery(unsigned int timeout = 4);
/**
* 停止發現SMB服務器
*/
int stopDiscovery();
/**
* 解析SMB服務器名字爲地址
*/
const char *resolve(const char *name);
/**
* 解析SMB服務器地址爲名字
*/
const char *inverse(const char *address);
/**
* 登錄SMB服務器
*/
int login(const char *host, const char *loginName, const char *password);
/**
* 登出SMB服務器
*/
int logout();
/**
* 獲取SMB服務器中共享的列表數據
*/
string *shareGetList();
/**
* 連接到共享目錄
*/
int treeConnect(const char *name);
/**
* 斷開共享目錄
*/
int treeDisconnect(int tid);
/**
* 獲取符合regex規則的文件
*/
string *find(int tid, const char *regex);
/**
* 獲取符合regex規則的文件狀態
*/
string *fileStatus(int tid, const char *path);
/**
* 當SMB服務器被發現時回調
*/
virtual void onDiscoveryEntryAdded(const char *json) = 0;
/**
* 當SMB服務器不可用時回調
*/
virtual void onDiscoveryEntryRemoved(const char *json) = 0;
具體源文件,此處可以查看:這裏
至此,核心模塊已經完成,也能順利的被鏈接到Android和iOS項目之中。
引用
- https://github.com/nlohmann/json