无法解析的外部符号是Windows下C++编译的常见链接错误,收集整理备忘.
本文随遇到的问题长期更新
我目前遇到的错误可以分为3类:
1.编译工具链修改了对应库函数的定义
2.编译参数导致定义和链接库不一致
3.库依赖冲突
4.未导入对应库
常见__imp__xxx未定义是因为导出函数前有__declspec(dllimport)
对于2,编译参数导致定义和链接库不一致
下列函数是因为VC编译选项产生
VC在/MD和/MDd编译选项时会定义_DLL宏,这时STL就定义了__declspec(dllimport),把项目(以及第三方依赖)的代码生成修改为/MT,/MTd即可.
#ifndef _ACRTIMP
#if defined _CRTIMP && !defined _VCRT_DEFINED_CRTIMP
#define _ACRTIMP _CRTIMP
#elif !defined _CORECRT_BUILD && defined _DLL
#define _ACRTIMP __declspec(dllimport)
#else
#define _ACRTIMP
#endif
#endif
__imp__strdup,__imp__stricmp,__imp__strspn,__imp_strncpy,__imp_fgets,__imp_strerror_s,__imp_open,__imp_close,__imp_read,__imp_write,__imp_unlink,__imp_wcscpy,__imp_clearerr,__imp_setbuf,__imp__chmod
__imp_getpid,__imp__wassert
(VS2019部分版本编译器,OpenSSL未MT编译)__imp___stricmp,__imp__clearerr,__imp__setbuf,__imp___chmod
对于3,库依赖冲突
常见是编译选择了静态运行时库(多线程(/MT)),然后手动添加了动态运行时库MSVCRT.LIB
__except_handler4_common
对于4,未导入对应库
列举常见未定义函数,以及对应库(Windows环境)
静态库 | error LNK2019: 无法解析的外部符号 |
---|---|
crypt32.lib | __imp__CertCloseStore@8,__imp__CertFreeCertificateContext@4,__imp__CertEnumCertificatesInStore@8,__imp__CertGetEnhancedKeyUsage@16,__imp__CertOpenSystemStoreW@8.... |
Wldap32.lib | __imp__ldap_initW,__imp__ldap_sslinitW,__imp__ldap_unbind_s,__imp__ldap_set_optionW,__imp__ldap_simple_bind_sW,__imp__ldap_search_sW __imp__ldap_msgfree,__imp__ldap_err2stringA,__imp__ldap_first_entry,__imp__ldap_next_entry,__imp__ldap_first_attributeW,__imp__ldap_next_attributeW __imp__ldap_get_values_lenW,__imp__ldap_value_free_len,__imp__ldap_get_dnW,__imp__ldap_memfreeW,__imp__ber_free |
附录:
openssl静态编译参数:
32位参数:VC-WIN32
调试版本: --debug
安装目录:--prefix="E:\OSP\openssl-1.1.1g\Win32"
静态库:no-shared
// 上述参数任意组合后加在Configure后面进行配置
#比如 perl Configure VC-WIN32 --debug no-shared
注意:静态库需要额外修改configdata.pm,makefile中的参数,MD(d)改成MT(d)
perl Configure VC-WIN32 --debug no-shared
nmake