• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2026-03-17 10:51 Aet 隐藏边栏 |   抢沙发  1 
文章评分 1 次,平均分 5.0

概述

  1. vcpkg安装了libcurl的静态库,把该静态库拷贝到了项目同级目录,并在项目中引用了这个libcurl.lib

问题

现象

  1. 编译出test.exe的时候发现,同时会多出两个文件
    1. libcurl.dll
    2. zlib1.dll

分析

  1. 在项目同级目录放进去的是静态库,也在项目中附近库目录指定了静态库所在路径,也在附加依赖项里面指定了libcurl.lib
  2. 先明确表示使用静态库
    1. 发现不生成libcurl.dll

  1. 但是出现了无法解析的外部符号, 类似__imp__getsockopt
    1. __imp_ 前缀 = 链接器在找 DLL导入版本 的 winsock 函数,说明:
    2. 可能还在链接旧的动态版 libcurl.lib(没换成静态版)
    3. 而静态版 curl 需要手动附加 Windows 依赖库(动态版会自动处理,静态版不会)
  2. 于是,附加静态链接所需的 Windows 依赖库
    1. 动态 libcurl.dll → 内部已经链接好 winsock,你不用管
    2. 静态 libcurl.lib → 所有依赖都要你自己显式告诉链接器

  1. 不报libcurl相关的LNK2001错误了
    1. 但是,还是会生成zlib1.dll
    2. 说明 libcurl 已经静态链接成功了,但项目里还有一个额外的动态 zlib 引用残留
  2. dumpbin 检查依赖
    1. 没有 libcurl.dll / zlib1.dll

  1. 验证 zlib.lib
    1. 发现没有输出,说明是静态库
    2. 如果有 __imp_ 输出 → 还是导入库
    3. 结果是没有输出

  1. 确认 zlib1.dll 是真的被链接了,还是别的原因
    1. 输出里没有 zlib1.dll → 说明 exe 本身不依赖它,是别的原因
    2. 输出里有 zlib1.dll → 说明 libcurl.lib 本身是用动态 zlib 编译的
    3. 可以看到有zlib1.dll,说明可能 libcurl.lib 本身编译时用的是动态 zlib

  1. 再验证一下libcurl.lib 本身编译时用的是不是动态 zlib
    1. 结果是没有看到任何输出

  1. 换个思路,看看 exe 具体从 zlib1.dll 导入了哪些函数
    1. 发现确实导入了
    2. 说明链接器找的 inflate 实现不是来自静态 zlib.lib

  1. 在链接器选项里临时加上 /VERBOSE:LIB,重新编译:
    1. 让链接器自己说出在找哪个
    2. 观察到确实在搜索zlib1,而且路径是vcpkg的路径

  1. 于是在vs项目设置里面关掉了使用vcpkg
  2. 问题解决了

其他

MT和静态库

  1. /MT 只管 MSVC 运行时(CRT)的链接方式,和 库本身是静态还是动态无关
    1. 所以说,并不是在项目里设置了mt,项目就会自动链接所有的静态库

声明:本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享