LIBDSM庫對多平臺、多方案支持的開發與探索 - Native Module

系列文章

項目地址 - https://github.com/biezhihua/libdsm

架構

在一開始之初,我對此處的設計目標是個獨立模塊,但是由於對C++不夠熟悉,並且爲了能夠快速debug調試,之後將目標改爲了能夠與Android和iOS工程一起進行源碼編譯。

因此,雙端的架構,也有略微的不同之處。

image.png

雙端大部分都是一致的,也符合最大複用原則,只有編譯環境部分是不同的。

下面介紹一些基礎模塊:

  • 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而言,這相對方便很多。

  1. 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
  1. Build Phases中的Compile Sources中,將如下源文件拖入其中:
libdsm_core/Dsm.cpp
  1. 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章