当前位置:   article > 正文

LIBDSM库对多平台、多方案支持的开发与探索 - Native Module

libdsm

系列文章

项目地址 - 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}

        )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

对于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 ()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

通过上面的组织后,打开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
  • 2
  • 3
  • 4
  1. Build Phases中的Compile Sources中,将如下源文件拖入其中:
libdsm_core/Dsm.cpp
  • 1
  1. Build Phases中的Headers中,将如下头文件拖入其中:
libdsm_core/nlohmann/json.h
libdsm_core/Log.h
libdsm_core/Dsm.h
distribution/ios/libdsm/include
  • 1
  • 2
  • 3
  • 4

实现

实现也很简单,用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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

具体源文件,此处可以查看:这里

至此,核心模块已经完成,也能顺利的被链接到Android和iOS项目之中。

引用

  • https://github.com/nlohmann/json
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/190905
推荐阅读
  

闽ICP备14008679号