解决下面的编译/链接问题过程中,有一些新的认识。
"warning LNK4049: locally defined symbol"
"error LNK2001: unresolved external symbol"
本文意在总结,讨论的中心自然也正如标题所言,是"C/C++ Runtime Library"
如果有副标题的话,我想我会用这些编译器的Warning与Error作为这篇blog的副标题。
和我以往的叙事习惯一样,共分为两部分。
第一部分首先描述我遇到的问题的现象,以及我探索的过程。
第二部分给出解决方案以及对这个问题的思考。
最后列出其他输入阅读的资源。
如果你更关心关于问题解得内容,那么请跳过第一部分。
一、问题现象 & 探索过程
1. 背景
公司最近有一个关于安全的项目,打算使用ssl技术,
应为公司以前就曾购买过RSA BSAFE SSL-C 这个库,自然我们的调查工作也就基于此展开。
(关于与他的是是非非,我还有很多话题想说)
给出的代码示例是拿"Visual Studio 2008 Command Prompt"的nmake编译的。
而我们的目的是要在工程里面使用他,
于是我们的第一步工作就是要在vc里面配置出个环境,是的我们可以展开针对他的编程工作。
发现的一些列问题,就是我分别在VS 2008和VC++ 6.0这两个IDE中配置sslc的环境而引发的。
2. 在VS2008中的问题
先说vs2008,导入那个sslc_standard.lib,自然地几步必不可少,
添加头文件库,添加这个lib库以及其他必须的库,定义一些他必须的宏。
(这些东西文档中没有,是我们痛苦的在那个makefile里面读出来的。)
在这些步骤完成后,本以为已经顺利搞定,
可Link的时候他还是出错。(错误信息与vc6的类似在此不错引用)
最终我在[Project] -> [Linker] -> [Input] -> [Ignore Specific Library]中
将msvcrt.lib忽略掉问题才算解决。
2. 在VC++ 6.0中的问题
虽然有了vs2008的经验,但在vc6的旅途并不轻松。
我把2008的那一套,在vc6重头到尾做一遍,发现仍然不行,错误信息如下:
我知道一定是两头的配置有什么地方不一样,
于是我就连diff连头项目的设置带google。
终于发现将下面位置的值从默认的"Debug Single-threaded"改成"Debug Multithreaded DLL"即可。
[Project] -> [Setting] -> [C++] -> [Code Generation] -> [Use run-time library]
(VS2008的runtime library的默认值也是Multi-threaded Debug DLL)
3.和我经历过同样问题的人
Qt-interest Archive, May 2001 Linker errors qt 3.0.0-snapshot-20010516
现象都是先说一堆:"warning LNK4049: locally defined symbol......"
再说一堆: "error LNK2001: unresolved external symbol....."
错误的地方都是一堆C标准函数。
二、总结 & 思考
这个问题的根本原因是C/C++ Runtime Library冲突的问题。
这个问题我个人本来是打算好好写一写的,但十分不幸的是,
我发现能写的内容都被Choosing the Correct C/C++ Runtime Library 的作者David 给写尽了。
作者没有写的问题也都在他的blog里面设置了到msdn的链接
另外,vs2008等后续vc中,已经取消了vc6中Debug Single-threaded的选项。
就其原因,上面的那篇blog中也有讨论。
下面是几篇msdn的帖子
Potential Errors Passing CRT Objects Across DLL Boundaries
这一篇讨论了为什么一个程序使用不同的crt可能会引发问题
这一篇介绍了微软都给我们提供了那些crt.
/MD, /ML, /MT, /LD (Use Run-Time Library)
这一主题共有好几个连接,讨论了不同编译器选项具体会使用那个crt,
三、其他资源
讨论了其他可能引起LNK2001的原因,包括由编译错误引起的,还有由链接错误引起的。
error LNK2001: unresolved external symbol _main
error LNK2001: unresolved external symbol _main解决办法
error LNK2001: unresolved external symbol _main解决办法(zz)
讨论了一些原因的解决办法,包括本文中遇到的crt问题。
这三个链接是重复的,之所以列出三个,是我想大家独到这儿的时候,至少有一个会是有效的。
其他:
有代码事例讨论了CRT,侧重Across DLL Boundary问题。
四、最后
附件是这篇上文提到的blog的pdf版本。
Choosing the Correct C/C++ Runtime Library