CMake进阶:vcpkg中OpenSSLConfig.cmake详解

目录

1.OpenSSLConfig.cmake

2.核心功能概述

3.细节分析

3.1.目标冲突检查(核心防重复逻辑)

3.2.根路径推导

[3.3.静态 / 动态库选择](#3.3.静态 / 动态库选择)

[3.4.版本 / 路径变量(兼容原生 FindOpenSSL)](#3.4.版本 / 路径变量(兼容原生 FindOpenSSL))

[3.5.vcpkg 多配置 / 单配置适配](#3.5.vcpkg 多配置 / 单配置适配)

3.6.静态库目标创建

3.7.动态库目标创建

[3.8.applink 目标(Windows 特有)](#3.8.applink 目标(Windows 特有))

4.使用方式

5.常见问题与解决方案

6.注意事项


1.OpenSSLConfig.cmake

windows用vcpkg安装OpenSSL,在目录:

.\vcpkg\packages\openssl_x64-windows\share\openssl\

下有OpenSSL的cmake引入文件OpenSSLConfig.cmake,如下:

打开这个文件,源码如下:

cpp 复制代码
# Generated by OpenSSL

# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)

# Avoid duplicate find_package()
set(_ossl_expected_targets OpenSSL::Crypto OpenSSL::SSL
    OpenSSL::applink)
set(_ossl_defined_targets)
set(_ossl_undefined_targets)
foreach(t IN LISTS _ossl_expected_targets)
  if(TARGET "${t}")
    LIST(APPEND _ossl_defined_targets "${t}")
  else()
    LIST(APPEND _ossl_undefined_targets "${t}")
  endif()
endforeach()
message(DEBUG "_ossl_expected_targets = ${_ossl_expected_targets}")
message(DEBUG "_ossl_defined_targets = ${_ossl_defined_targets}")
message(DEBUG "_ossl_undefined_targets = ${_ossl_undefined_targets}")
if(NOT _ossl_undefined_targets)
  # All targets are defined, we're good, just undo everything and return
  unset(_ossl_expected_targets)
  unset(_ossl_defined_targets)
  unset(_ossl_undefined_targets)
  unset(CMAKE_IMPORT_FILE_VERSION)
  return()
endif()
if(_ossl_defined_targets)
  # We have a mix of defined and undefined targets.  This is hard to reconcile,
  # and probably the result of another config, or FindOpenSSL.cmake having been
  # called, or whatever.  Therefore, the best course of action is to quit with a
  # hard error.
  message(FATAL_ERROR "Some targets defined, others not:\nNot defined: ${_ossl_undefined_targets}\nDefined: ${_ossl_defined_targets}")
endif()
unset(_ossl_expected_targets)
unset(_ossl_defined_targets)
unset(_ossl_undefined_targets)


# Set up the import path, so all other import paths are made relative this file
get_filename_component(_ossl_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_ossl_prefix "${_ossl_prefix}" PATH)
get_filename_component(_ossl_prefix "${_ossl_prefix}" PATH)

if(_ossl_prefix STREQUAL "/")
  set(_ossl_prefix "")
endif()


if(OPENSSL_USE_STATIC_LIBS)
  set(_ossl_use_static_libs True)
elseif(DEFINED OPENSSL_USE_STATIC_LIBS)
  # We know OPENSSL_USE_STATIC_LIBS is defined and False
  if(_ossl_use_static_libs)
    # OPENSSL_USE_STATIC_LIBS is explicitly false, indicating that shared libraries are
    # required.  However, _ossl_use_static_libs indicates that no shared libraries are
    # available.  The best course of action is to simply return and leave it to CMake to
    # use another OpenSSL config.
    unset(_ossl_use_static_libs)
    unset(CMAKE_IMPORT_FILE_VERSION)
    return()
  endif()
endif()

# Version, copied from what find_package() gives, for compatibility with FindOpenSSL.cmake
set(OPENSSL_VERSION "${OpenSSL_VERSION}")
set(OPENSSL_VERSION_MAJOR "${OpenSSL_VERSION_MAJOR}")
set(OPENSSL_VERSION_MINOR "${OpenSSL_VERSION_MINOR}")
set(OPENSSL_VERSION_FIX "${OpenSSL_VERSION_PATCH}")
set(OPENSSL_FOUND YES)

# Directories and names
set(OPENSSL_LIBRARY_DIR "${_ossl_prefix}/lib")
set(OPENSSL_INCLUDE_DIR "${_ossl_prefix}/include")
set(OPENSSL_ENGINES_DIR "${_ossl_prefix}/lib/engines-3")
set(OPENSSL_MODULES_DIR "${_ossl_prefix}/lib/../bin")
set(OPENSSL_RUNTIME_DIR "${_ossl_prefix}/bin")

set(OPENSSL_APPLINK_SOURCE "${_ossl_prefix}/include/openssl/applink.c")

set(OPENSSL_PROGRAM "${OPENSSL_RUNTIME_DIR}/openssl.exe")

if(NOT Z_VCPKG_OPENSSL_USE_SINGLE_CONFIG)
  # Prevent loop
  set(Z_VCPKG_OPENSSL_USE_SINGLE_CONFIG "prevent-loop")
  # Chainload vcpkg's module-based multi-config target setup
  find_package(OpenSSL MODULE)
  set(Z_VCPKG_OPENSSL_USE_SINGLE_CONFIG 0)
else()
  # Use official single-config target setup
# Set up the imported targets
if(_ossl_use_static_libs)

  add_library(OpenSSL::Crypto STATIC IMPORTED)
  add_library(OpenSSL::SSL STATIC IMPORTED)

  set(OPENSSL_LIBCRYPTO_STATIC "${OPENSSL_LIBRARY_DIR}/libcrypto_static.lib")
  set(OPENSSL_LIBCRYPTO_DEPENDENCIES ws2_32.lib gdi32.lib advapi32.lib crypt32.lib user32.lib)
  set_target_properties(OpenSSL::Crypto PROPERTIES
    IMPORTED_LINK_INTERFACE_LANGUAGES "C"
    IMPORTED_LOCATION ${OPENSSL_LIBCRYPTO_STATIC})
  set_property(TARGET OpenSSL::Crypto
    PROPERTY INTERFACE_LINK_LIBRARIES ${OPENSSL_LIBCRYPTO_DEPENDENCIES})

  set(OPENSSL_LIBSSL_STATIC "${OPENSSL_LIBRARY_DIR}/libssl_static.lib")
  set(OPENSSL_LIBSSL_DEPENDENCIES OpenSSL::Crypto)
  set_target_properties(OpenSSL::SSL PROPERTIES
    IMPORTED_LINK_INTERFACE_LANGUAGES "C"
    IMPORTED_LOCATION ${OPENSSL_LIBSSL_STATIC})
  set_property(TARGET OpenSSL::SSL
    PROPERTY INTERFACE_LINK_LIBRARIES ${OPENSSL_LIBSSL_DEPENDENCIES})

  # Directories and names compatible with CMake's FindOpenSSL.cmake
  set(OPENSSL_CRYPTO_LIBRARY ${OPENSSL_LIBCRYPTO_STATIC})
  set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY} ${OPENSSL_LIBCRYPTO_DEPENDENCIES})
  set(OPENSSL_SSL_LIBRARY ${OPENSSL_LIBSSL_STATIC})
  set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_LIBSSL_DEPENDENCIES})
  set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_LIBSSL_DEPENDENCIES} ${OPENSSL_LIBCRYPTO_DEPENDENCIES})

else()

  add_library(OpenSSL::Crypto SHARED IMPORTED)
  add_library(OpenSSL::SSL SHARED IMPORTED)

  set(OPENSSL_LIBCRYPTO_SHARED "${OPENSSL_RUNTIME_DIR}/libcrypto-3-x64.dll")
  set(OPENSSL_LIBCRYPTO_IMPORT "${OPENSSL_LIBRARY_DIR}/libcrypto.lib")
  set(OPENSSL_LIBCRYPTO_DEPENDENCIES )
  set_target_properties(OpenSSL::Crypto PROPERTIES
    IMPORTED_LINK_INTERFACE_LANGUAGES "C"
    IMPORTED_IMPLIB ${OPENSSL_LIBCRYPTO_IMPORT}
    IMPORTED_LOCATION ${OPENSSL_LIBCRYPTO_SHARED})
  set_property(TARGET OpenSSL::Crypto
    PROPERTY INTERFACE_LINK_LIBRARIES ${OPENSSL_LIBCRYPTO_DEPENDENCIES})

  set(OPENSSL_LIBSSL_SHARED "${OPENSSL_RUNTIME_DIR}/libssl-3-x64.dll")
  set(OPENSSL_LIBSSL_IMPORT "${OPENSSL_LIBRARY_DIR}/libssl.lib")
  set(OPENSSL_LIBSSL_DEPENDENCIES OpenSSL::Crypto )
  set_target_properties(OpenSSL::SSL PROPERTIES
    IMPORTED_LINK_INTERFACE_LANGUAGES "C"
    IMPORTED_IMPLIB ${OPENSSL_LIBSSL_IMPORT}
    IMPORTED_LOCATION ${OPENSSL_LIBSSL_SHARED})
  set_property(TARGET OpenSSL::SSL
    PROPERTY INTERFACE_LINK_LIBRARIES ${OPENSSL_LIBSSL_DEPENDENCIES})

  # Directories and names compatible with CMake's FindOpenSSL.cmake
  set(OPENSSL_CRYPTO_LIBRARY ${OPENSSL_LIBCRYPTO_IMPORT})
  set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY} ${OPENSSL_LIBCRYPTO_DEPENDENCIES})
  set(OPENSSL_SSL_LIBRARY ${OPENSSL_LIBSSL_IMPORT})
  set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_LIBSSL_DEPENDENCIES})
  set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_LIBSSL_DEPENDENCIES} ${OPENSSL_LIBCRYPTO_DEPENDENCIES})


endif()

set_target_properties(OpenSSL::Crypto PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}")
set_target_properties(OpenSSL::SSL PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "${OPENSSL_INCLUDE_DIR}")


add_library(OpenSSL::applink INTERFACE IMPORTED)
set_property(TARGET OpenSSL::applink PROPERTY
  INTERFACE_SOURCES "${OPENSSL_APPLINK_SOURCE}")


endif()
unset(_ossl_prefix)
unset(_ossl_use_static_libs)

核心作用是为 CMake 项目导入 OpenSSL 的预编译库(静态 / 动态),并兼容 CMake 原生的FindOpenSSL.cmake接口。下面就来仔细说说OpenSSL的CMake引入文件。

2.核心功能概述

  1. 避免重复导入:检查 OpenSSL 的核心目标(OpenSSL::Crypto/OpenSSL::SSL/OpenSSL::applink)是否已定义,防止重复配置或冲突;
  2. 路径自动推导:从配置文件路径向上推导 OpenSSL 的安装根目录;
  3. 静态 / 动态库适配:根据OPENSSL_USE_STATIC_LIBS变量选择静态 / 动态库;
  4. 兼容 vcpkg 多配置:区分 vcpkg 的多配置(MODULE 模式)和单配置目标;
  5. 导入目标创建:定义标准的 OpenSSL CMake 导入目标,兼容原生 FindOpenSSL 接口。

3.细节分析

3.1.目标冲突检查(核心防重复逻辑)

cpp 复制代码
# 预期的OpenSSL目标列表
set(_ossl_expected_targets OpenSSL::Crypto OpenSSL::SSL OpenSSL::applink)
# 遍历检查目标是否已定义
foreach(t IN LISTS _ossl_expected_targets)
  if(TARGET "${t}")
    LIST(APPEND _ossl_defined_targets "${t}")
  else()
    LIST(APPEND _ossl_undefined_targets "${t}")
  endif()
endforeach()
# 全部已定义:直接返回(避免重复)
if(NOT _ossl_undefined_targets)
  unset(...)
  return()
endif()
# 部分已定义:报错(冲突无法调和)
if(_ossl_defined_targets)
  message(FATAL_ERROR "Some targets defined, others not:...")
endif()
  • 作用:防止多次调用find_package(OpenSSL)或混合不同版本的 OpenSSL 配置导致目标冲突;
  • 关键:如果已有部分 OpenSSL 目标被定义,直接报错(避免混合静态 / 动态库、不同版本)。

这里涉及到一个指令**TARGET,它的语法如下:**

cpp 复制代码
if(TARGET <target-name>)
  # 目标存在时执行的逻辑
else()
  # 目标不存在时执行的逻辑
endif()
  • 返回 TRUE:目标已通过 add_executable/add_library/find_package(导入)等方式创建;
  • 返回 FALSE:目标未创建,或名称拼写错误(含大小写)。

为什么要做这个判断?

  • 避免重复创建目标 :若 find_package(OpenSSL) 被多次调用,第一次会创建 OpenSSL::Crypto 等目标,第二次若不检查直接创建,会触发 CMake 报错("目标已存在");
  • 防止混合配置冲突 :若部分目标已创建(如 OpenSSL::Crypto 是静态库)、部分未创建(如 OpenSSL::SSL),强行创建剩余目标会导致 "静态 / 动态库混用""版本不一致" 等链接错误;
  • 快速失败原则 :若检测到 "部分目标存在、部分不存在",直接报错(message(FATAL_ERROR)),而非隐式兼容,避免后续更难排查的链接问题。

为什么要做 "全定义 / 全未定义" 检查?

  • 若 "部分定义"(比如OpenSSL::Crypto已定义,OpenSSL::SSL未定义),大概率是:
    1. 多次调用find_package(OpenSSL)
    2. 混合了不同版本的 OpenSSL 配置(比如静态库和动态库混用);
    3. 手动创建过其中一个目标,与配置文件冲突。
  • 这种情况下继续配置会导致链接错误、版本不一致等问题,因此直接报错是最安全的选择。

3.2.根路径推导

cpp 复制代码
get_filename_component(_ossl_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_ossl_prefix "${_ossl_prefix}" PATH)
get_filename_component(_ossl_prefix "${_ossl_prefix}" PATH)
if(_ossl_prefix STREQUAL "/")
  set(_ossl_prefix "")
endif()
  • 逻辑:从当前配置文件路径向上退 3 级(对应 vcpkg 的installed/<triplet>/share/openssl → 根目录);
  • 示例:若配置文件路径是D:/vcpkg/installed/x64-windows/share/openssl/OpenSSLConfig.cmake,则_ossl_prefix最终为D:/vcpkg/installed/x64-windows

get_filename_component 是 CMake 中路径 / 文件名解析的核心内置指令,用于提取文件路径的任意组成部分(目录、文件名、扩展名、绝对路径等)。

3.3.静态 / 动态库选择

cpp 复制代码
if(OPENSSL_USE_STATIC_LIBS)
  set(_ossl_use_static_libs True)
elseif(DEFINED OPENSSL_USE_STATIC_LIBS)
  # 显式禁用静态库但无动态库时,返回(让CMake找其他配置)
  if(_ossl_use_static_libs)
    return()
  endif()
endif()
  • 触发条件:
    • OPENSSL_USE_STATIC_LIBS=ON → 使用静态库(libcrypto_static.lib/libssl_static.lib);
    • 未设置或设为OFF → 使用动态库(libcrypto.lib+libcrypto-3-x64.dll)。

3.4.版本 / 路径变量(兼容原生 FindOpenSSL)

cpp 复制代码
# 版本变量(对接find_package(OpenSSL REQUIRED VERSION ...))
set(OPENSSL_VERSION "${OpenSSL_VERSION}")
set(OPENSSL_VERSION_MAJOR "${OpenSSL_VERSION_MAJOR}")
# 路径变量
set(OPENSSL_LIBRARY_DIR "${_ossl_prefix}/lib")       # 库文件目录
set(OPENSSL_INCLUDE_DIR "${_ossl_prefix}/include")   # 头文件目录
set(OPENSSL_RUNTIME_DIR "${_ossl_prefix}/bin")       # DLL/可执行文件目录
set(OPENSSL_APPLINK_SOURCE "${_ossl_prefix}/include/openssl/applink.c") # Windows MSVC必需
  • 关键:applink.c是 Windows 下 MSVC 使用 OpenSSL 动态库的必要文件(解决 CRT 链接问题)。

在这里引入了OpenSSL的版本变量 OPENSSL_VERSION、OPENSSL_VERSION_MAJOR

OpenSSL的包含头文件目录、库文件目录等等。

3.5.vcpkg 多配置 / 单配置适配

cpp 复制代码
if(NOT Z_VCPKG_OPENSSL_USE_SINGLE_CONFIG)
  # 多配置:链式调用vcpkg的MODULE模式配置
  set(Z_VCPKG_OPENSSL_USE_SINGLE_CONFIG "prevent-loop")
  find_package(OpenSSL MODULE)
  set(Z_VCPKG_OPENSSL_USE_SINGLE_CONFIG 0)
else()
  # 单配置:创建原生导入目标
  ...
endif()
  • 背景:vcpkg 支持 "多配置"(如 Debug/Release 共存)和 "单配置",这里通过标记变量避免循环调用。

3.6.静态库目标创建

CMake指令:add_library

cpp 复制代码
add_library(OpenSSL::Crypto STATIC IMPORTED)
add_library(OpenSSL::SSL STATIC IMPORTED)
# 设置libcrypto静态库路径和依赖(Windows系统库)
set(OPENSSL_LIBCRYPTO_STATIC "${OPENSSL_LIBRARY_DIR}/libcrypto_static.lib")
set(OPENSSL_LIBCRYPTO_DEPENDENCIES ws2_32.lib gdi32.lib advapi32.lib crypt32.lib user32.lib)
set_target_properties(OpenSSL::Crypto PROPERTIES
  IMPORTED_LINK_INTERFACE_LANGUAGES "C"
  IMPORTED_LOCATION ${OPENSSL_LIBCRYPTO_STATIC})
set_property(TARGET OpenSSL::Crypto PROPERTY INTERFACE_LINK_LIBRARIES ${OPENSSL_LIBCRYPTO_DEPENDENCIES})
# libssl依赖libcrypto
set(OPENSSL_LIBSSL_STATIC "${OPENSSL_LIBRARY_DIR}/libssl_static.lib")
set(OPENSSL_LIBSSL_DEPENDENCIES OpenSSL::Crypto)
  • 静态库依赖:libcrypto需要链接 Windows 系统库(如ws2_32是网络库,crypt32是加密 API);
  • 接口传递:依赖会自动传递给链接OpenSSL::SSL的目标。

IMPORTED_LINK_INTERFACE_LANGUAGES 是 CMake 中导入目标(IMPORTED Target) 的核心属性,直译是「导入的链接接口语言」,核心作用是告诉 CMake:这个预编译的导入库(如 OpenSSL 的静态 / 动态库)是用哪种 / 哪些编程语言编译的,CMake 会基于该信息处理链接阶段的语言适配、编译器标志传递等逻辑。

为什么必须设置?

以 OpenSSL 为例:libcrypto/libssl纯 C 编写 的库,如果不指定 IMPORTED_LINK_INTERFACE_LANGUAGES "C"

  • CMake 可能会默认按当前目标的语言(比如 C++)处理,给链接阶段添加不必要的 C++ 标志(如 -lstdc++);
  • 极端场景下(如 C++ 目标链接纯 C 库),可能因语言标志冲突导致「未定义符号」(比如 C++ 的 name mangling 干扰 C 符号)。

3.7.动态库目标创建

cpp 复制代码
add_library(OpenSSL::Crypto SHARED IMPORTED)
add_library(OpenSSL::SSL SHARED IMPORTED)
# 动态库需要指定DLL路径(IMPORTED_LOCATION)和导入库(IMPORTED_IMPLIB)
set_target_properties(OpenSSL::Crypto PROPERTIES
  IMPORTED_LINK_INTERFACE_LANGUAGES "C"
  IMPORTED_IMPLIB ${OPENSSL_LIBCRYPTO_IMPORT}  # .lib导入库
  IMPORTED_LOCATION ${OPENSSL_LIBCRYPTO_SHARED}) # .dll运行时
  • 关键区别:动态库需要同时指定IMPORTED_IMPLIB(链接时用的.lib)和IMPORTED_LOCATION(运行时用的.dll)。
cpp 复制代码
add_library(OpenSSL::applink INTERFACE IMPORTED)
set_property(TARGET OpenSSL::applink PROPERTY
  INTERFACE_SOURCES "${OPENSSL_APPLINK_SOURCE}")
  • 作用:MSVC 编译时,applink.c会被自动包含,解决 OpenSSL 动态库与 CRT 的链接冲突。

4.使用方式

1.基础使用(vcpkg 环境)

cpp 复制代码
# 安装OpenSSL(vcpkg)
# vcpkg install openssl:x64-windows (动态库)
# vcpkg install openssl:x64-windows-static (静态库)

# CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(openssl_demo)

# 启用静态库(可选)
# set(OPENSSL_USE_STATIC_LIBS ON)

# 查找OpenSSL
find_package(OpenSSL REQUIRED)

# 链接目标
add_executable(demo main.c)
target_link_libraries(demo PRIVATE OpenSSL::SSL OpenSSL::Crypto OpenSSL::applink)

2.非 vcpkg 环境

需确保:

  • 配置文件路径正确,_ossl_prefix能推导到 OpenSSL 安装根目录;
  • 静态 / 动态库文件存在于对应目录;
  • Windows 系统库(如ws2_32.lib)可被 CMake 找到。

5.常见问题与解决方案

1.报错 "Some targets defined, others not"

  • 原因:多次调用find_package(OpenSSL),或混合了不同版本的 OpenSSL 配置;
  • 解决:
    • 确保只调用一次find_package(OpenSSL)
    • 清除 CMake 缓存(CMakeCache.txt)后重新配置;
    • 检查是否手动定义过OpenSSL::Crypto等目标。

2.静态库链接时缺少系统库

  • 现象:链接报错unresolved external symbol(如WSAStartup);
  • 解决:确保代码中已链接OpenSSL::Crypto(会自动传递系统库依赖),或手动链接:
cpp 复制代码
target_link_libraries(demo PRIVATE ws2_32.lib advapi32.lib crypt32.lib)

3.动态库运行时缺少 DLL

  • 现象:运行程序提示libcrypto-3-x64.dll缺失;
  • 解决:
    • OPENSSL_RUNTIME_DIR(如vcpkg/installed/x64-windows/bin)加入系统 PATH;
    • 或复制 DLL 到程序输出目录:
cpp 复制代码
add_custom_command(TARGET demo POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy_if_different
  $<TARGET_FILE:OpenSSL::Crypto>
  $<TARGET_FILE_DIR:demo>
)
add_custom_command(TARGET demo POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy_if_different
  $<TARGET_FILE:OpenSSL::SSL>
  $<TARGET_FILE_DIR:demo>
)

4.MSVC 编译报错 "applink.c missing"

  • 原因:未链接OpenSSL::applink目标;
  • 解决:在target_link_libraries中加入OpenSSL::applink

6.注意事项

  1. 平台限制 :该配置仅适用于 Windows(包含openssl.exe.dll、Windows 系统库依赖);
  2. vcpkg 依赖 :代码中Z_VCPKG_OPENSSL_USE_SINGLE_CONFIG是 vcpkg 特有标记,非 vcpkg 环境需移除相关逻辑;
  3. 版本兼容 :适配 OpenSSL 3.x(库文件名libcrypto-3-x64.dll),2.x 需调整库文件名;
  4. CRT 一致性:静态库需确保与项目的 CRT(MD/MT)一致,否则会报链接错误。
相关推荐
郑同学的笔记19 小时前
【Eigen教程02】深入Eigen矩阵引擎:模板参数、内存布局与基础操作指南
c++·线性代数·矩阵·eigen
wadesir20 小时前
C++基本数据类型详解(零基础掌握C++核心数据类型)
java·开发语言·c++
leiming621 小时前
c++ map容器
开发语言·c++·算法
多多*1 天前
2026年1月3日八股记录
java·开发语言·windows·tcp/ip·mybatis
杨校1 天前
杨校老师课堂备赛C++信奥之模拟算法习题专项训练
开发语言·c++·算法
hd51cc1 天前
MFC 文档/视图 二
c++·mfc
nnsix1 天前
Windows 将桌面 路径 从C盘 移动到D盘
windows
wzfj123451 天前
认识lambda
c++
老王熬夜敲代码1 天前
C++万能类:any
开发语言·c++·笔记