因业务需要开发新的游戏平台,要实现对于游戏文件的二次打包压缩处理和解压,这里采用了VS2019对于 zip1 的压缩源码进行了封装。但是其中报错了如题。
用MTD动态编译没问题,但是用MDT静态编译就有问题了,提示 无法解析的外部符号 _imp_XXXXXXXXX。
那么对于这个问题 很多人解决的是 缺少第三方的 lib,但是这个并不是缺第三方,而是缺系统自带的lib引用,如果你用的是静态编译 MDT+Debug模式的话,就把下面这三句代码放入你的代码页里面就,错误可就不会有了。之前一直以为是 缺三方的 lib,确实我这里用了第三方的 模块 zip1.lib这种压缩模块
#pragma comment(lib, "msvcrtd.lib")
#pragma comment(lib, "vcruntimed.lib")
#pragma comment(lib, "ucrtd.lib")
错误信息如下:
1>Dictionary.obj : error LNK2019: 无法解析的外部符号 ___stdio_common_vfprintf,该符号在函数 __vfprintf_l 中被引用
1>Log.obj : error LNK2001: 无法解析的外部符号 ___stdio_common_vfprintf
1>ExcelAddin4J.obj : error LNK2001: 无法解析的外部符号 ___stdio_common_vsprintf
1>Classpath.obj : error LNK2001: 无法解析的外部符号 ___stdio_common_vsprintf
1>VM.obj : error LNK2001: 无法解析的外部符号 ___stdio_common_vsprintf
1>Dictionary.obj : error LNK2001: 无法解析的外部符号 ___stdio_common_vsprintf
1>Icon.obj : error LNK2001: 无法解析的外部符号 ___stdio_common_vsprintf
1>INI.obj : error LNK2001: 无法解析的外部符号 ___stdio_common_vsprintf
1>Log.obj : error LNK2001: 无法解析的外部符号 ___stdio_common_vsprintf
1>Dictionary.obj : error LNK2019: 无法解析的外部符号 ___stdio_common_vsscanf,该符号在函数 __vsscanf_l 中被引用
1>Log.obj : error LNK2019: 无法解析的外部符号 ___acrt_iob_func,该符号在函数 "public: static void __cdecl Log::Init(struct HINSTANCE__ *,char const *,char const *)" (?Init@Log@@SAXPAUHINSTANCE__@@PBD1@Z) 中被引用
1>Log.obj : error LNK2019: 无法解析的外部符号 __fdopen,该符号在函数 "private: static void __cdecl Log::RedirectIOToConsole(void)" (?RedirectIOToConsole@Log@@CAXXZ) 中被引用
1>Log.obj : error LNK2019: 无法解析的外部符号 ___stdio_common_vsprintf_s,该符号在函数 __vsprintf_s_l 中被引用
1>D:\dev\workspace\excel\xll\winrun4j\prj\\build\ExcelAddin4J-Debug\ExcelAddin4J.xll : fatal error LNK1120: 6 个无法解析的外部命令
原理上是引用库有问题,但查阅众多资料,反复测试也没有太多进展,折腾得我快想放弃此工程了。
无意中看到一篇关于link库文件问题文章:
就把其中的:
#pragma comment(lib, "msvcrtd.lib")
#pragma comment(lib, "vcruntimed.lib")
#pragma comment(lib, "ucrtd.lib")
放到CPP文件中测试,居然居然好了,太TMD的意外了。
赶紧测试编译出来的xll文件是否正常,也记录此次编译的解决方法,以供遇到类似问题的同行参考。
//
我不明白为什么一定要手动指定 main 函数作为入口。使用默认的 mainCRTStartup 显然是更安全的选项。
如果一定要这样做可以使用下面的方法手动链接运行库。
#pragma comment(lib, "msvcrtd.lib")
#pragma comment(lib, "vcruntimed.lib")
#pragma comment(lib, "ucrtd.lib")
需要根据自己的编译选项来确定链接哪些库
Release DLLs (/MD ): msvcrt.lib vcruntime.lib ucrt.lib
Debug DLLs (/MDd): msvcrtd.lib vcruntimed.lib ucrtd.lib
Release Static (/MT ): libcmt.lib libvcruntime.lib libucrt.lib
Debug Static (/MTd): libcmtd.lib libvcruntimed.lib libucrtd.lib