VS2017使用GSL 2.4编译运行时出现___iob_func未解析外部符号错误
解决VS2017使用GSL 2.4时的___iob_func未解析外部符号错误
我之前在VS2017里折腾GSL 2.4的时候,也碰到过和你完全一样的LNK2019/LNK2001错误,这个问题的核心是VS 2015之后的C运行时库(CRT)更新了标准IO的实现,而预编译的GSL 2.4可能是用旧版VS编译的,导致链接时找不到旧版符号___iob_func。下面给你几个亲测有效的解决办法:
方法一:快速兼容(治标)
在你的项目里新增一个cpp文件(比如crt_compat.cpp),或者在现有主文件的开头加入以下代码:
#include <cstdio> // 把新版CRT的标准IO对象映射到旧版符号上 extern "C" { FILE __iob_func[3] = { *stdin, *stdout, *stderr }; }
添加完之后重新编译链接,这个方法相当于给GSL做了个符号兼容层,能快速解决问题。
方法二:重新编译GSL(治本)
如果不想用兼容层,最好的办法是用VS2017自己编译GSL源码,确保库和你的开发环境完全匹配:
- 下载GSL 2.4的源码包并解压
- 打开VS2017的开发者命令提示符(一定要用这个,不然cmake找不到VS环境)
- 进入源码根目录,运行cmake命令生成VS解决方案:
# 64位项目用这个 cmake -G "Visual Studio 15 2017" -A x64 . # 32位项目换成 Win32 cmake -G "Visual Studio 15 2017" -A Win32 . - 生成后打开
ALL_BUILD.vcxproj,编译Debug和Release版本,得到适配VS2017的gsl.lib和gslcblas.lib,替换你项目里原来的库文件即可。
方法三:调整项目CRT配置(谨慎使用)
右键你的项目 → 属性 → 配置属性 → C/C++ → 代码生成 → 运行时库,把选项改成和GSL编译时一致的版本:
- 如果GSL是用多线程DLL编译的,选
/MD(Release)或/MDd(Debug) - 如果是静态多线程编译的,选
/MT(Release)或/MTd(Debug)
注意:这个方法可能会影响你项目其他依赖的CRT版本,容易引发其他兼容问题,除非你确定GSL的CRT版本,否则优先用前两种方法。
另外还要检查一下:你的项目平台(x86/x64)必须和GSL库的平台完全一致,不然也会出现类似的链接错误哦。
内容的提问来源于stack exchange,提问作者theQuantumMechanic
相关产品推荐
相关产品推荐

