库文件编译源码-CLion编译和使用动态库

1、使用Clion开发动态库文件 1.1 动态库简介

注:在Linux平台下,动态库和静态库的源码是完全一样的,只需要改变编译参数即可。 Windows平台上生成的动态库的源代码与静态库是不同的。

在Windows平台上,当我们导入动态库时,不仅会生成.dll动态库,还会生成.lib文件。 这个.lib文件与静态库的.lib文件不同。 它保存的不是代码生成的二补码文件,而是所有需要导入符号符号表。 因此库文件编译源码,这个.lib文件会比编译静态库生成的.lib文件小很多。 而这个导入的符号表需要在源码中指定。 如果我们要导入一个符号(symbol)(这里的符号可以指类、函数等各种类型),我们需要在其后面添加__declspec(dllexport)标志。 这样,这个符号的相关信息就会被导入到.lib中的符号表中。 如果我们的源码中没有__declspec(dllexport),我们仍然可以成功编译动态库,并且不会生成保存符号表的.lib文件。 这也是Windows平台下编译动态库时的常见问题。 如果我们的源码是在Linux平台下编译的,很容易忘记改源码。

原文链接:

上面说了,在windows下实现动态库源码的跨平台特性会比较麻烦,不过好在cmake有自己的解决方案,只要知道原理是什么就可以了。

1.2 新建一个Library项目

1.3 CmakeLists.txt的设置

GenerateExportHeader—CMake3.24.0-rc3文档

cmake_minimum_required(VERSION 3.22)
set(CMAKE_CXX_STANDARD 14)
project(MyDLL)
# 导入 GenerateExportHeader 函数
include(GenerateExportHeader)
#set(CMAKE_CXX_VISIBILITY_PRESET hidden)
#set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
# 判断是否是debug模式,如果是debug,则后缀加‘d',比如 MyDLLd.dll MyDLLd.lib
set(DEBUG_SUFFIX)
if (MSVC AND CMAKE_BUILD_TYPE MATCHES "Debug")
    set(DEBUG_SUFFIX "d")
endif ()
# CMAKE_DEBUG_POSTFIX 全局变量用于附加 d对于调试库:
set(CMAKE_DEBUG_POSTFIX d)
# 定义目标名称变量
set(TargetName ${PROJECT_NAME})
message(${TargetName})
# 生成 动态的 MyDLL.dll 文件
add_library(${TargetName} SHARED library.cpp)
# MyDLL export宏定义, 生成的文件名为 mydll_export.h, 路径: ${PROJECT_BINARY_DIR}
GENERATE_EXPORT_HEADER(${TargetName})
INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
# 设置安装目录
SET(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR}/${PROJECT_NAME}_lib)
# 拷贝头文件 到 include 目录下
INSTALL(FILES library.h ${PROJECT_BINARY_DIR}/mydll_export.h  DESTINATION include)
# 将 dll 和 lib 库文件 分别放到 lib 和 bin 目录下
INSTALL(TARGETS ${TargetName} LIBRARY DESTINATION lib)

ReloadCmakeProject后,在项目的补码目录下手动生成mydll_export.h

1.4 ABI文件导出mydll_export.h

导出头文件后,使用MYDLL_EXPORT声明各处的函数

1.5 创建项目

项目建立并执行后,会生成相关的库文件,如右图所示:

库文件编译源码-CLion编译和使用动态库

1.6 安装

点击安装后库文件编译源码,会手动将库文件放到对应的目录下

2.使用第三方动态库文件

动态库使用生成的MyDLL

2.1 新项目

2.2 将MyDLL库文件复制到源代码目录

库文件编译源码-CLion编译和使用动态库

2.3 CmakeLists.txt的设置

cmake_minimum_required(VERSION 3.22)
project(UseDLL)
set(CMAKE_CXX_STANDARD 14)
# 判断是否是debug模式,如果是debug,则后缀加‘d',比如 MyDLLd.dll MyDLLd.lib
set(DEBUG_SUFFIX)
if (MSVC AND CMAKE_BUILD_TYPE MATCHES "Debug")
    set(DEBUG_SUFFIX "d")
endif ()
# CMAKE_DEBUG_POSTFIX 全局变量用于附加 d对于调试库:
#set(CMAKE_DEBUG_POSTFIX d)  # 这玩意在使用库文件的时候,似乎没有用处
add_executable(UseDLL main.cpp)
#INCLUDE_DIRECTORIES(MyDLL_lib/include)  # 这种方式也可以导入库文件
# 为目标添加 include 目录
target_include_directories(UseDLL
        PUBLIC
        ${PROJECT_SOURCE_DIR}/MyDLL_lib/include)
message(${PROJECT_SOURCE_DIR}/MyDLL_lib/lib/MyDLL${DEBUG_SUFFIX})
# 为目标 链接添加 lib文件
target_link_libraries(UseDLL
        PRIVATE
        ${PROJECT_SOURCE_DIR}/MyDLL_lib/lib/MyDLL${DEBUG_SUFFIX}.lib)
# 这种用目录的方式处理的不是很好,需要明确指定到lib的文件名,应该有其他的方式

2.4 使用库中的头文件

2.5 编译运行

将dll文件复制到补码目录下,然后编译运行

成功复制“你好,世界!”

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 源码编译 库文件编译源码-CLion编译和使用动态库 https://www.wkzy.net/game/167805.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务