编译出现: error LNK2019: 无法解析的外部符号 ___stdio_common_vfprintf

转自:http://blog.chinaunix.net/uid-2384984-id-5784738.html?tdsourcetag=s_pctim_aiomsg  

因业务需要用java开发Excel插件, 编译ExcelAddin4J C++工程时,遇到了这个错误。原因是在vs2015->配置属性->C/C++->代码生成->安全检查:禁用安全检查 (/GS-)。sprinf此函数实现调用
___stdio_common_vfprintf引起的,这是一个最基本的C++函数。若起用安全检查 (/GS-)则会报其它错误,启用它报的错误类型就它,估计解决要容易些,因此选择集中精力来解决它,错误信息如下:

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库文件问题文章:https://www.v2ex.com/amp/t/366594
就把其中的:
#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

发表评论

电子邮件地址不会被公开。 必填项已用*标注