选择正确的C/C++ Runtime Library

解决下面的编译/链接问题过程中,有一些新的认识。

"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重头到尾做一遍,发现仍然不行,错误信息如下:

 

错误信息
Linking...
LINK : warning LNK4049: locally defined symbol "_sprintf" imported
LINK : warning LNK4049: locally defined symbol "_strncmp" imported
LINK : warning LNK4049: locally defined symbol "_fclose" imported
LINK : warning LNK4049: locally defined symbol "_fflush" imported
LINK : warning LNK4049: locally defined symbol "__pctype" imported
LINK : warning LNK4049: locally defined symbol "__isctype" imported
......................
sslc_standard.lib(bss_file.obj) : error LNK2001: unresolved external symbol __imp__fread
sslc_standard.lib(entropy.obj) : error LNK2001: unresolved external symbol __imp__fread
sslc_standard.lib(bss_file.obj) : error LNK2001: unresolved external symbol __imp__fwrite
sslc_standard.lib(bss_file.obj) : error LNK2001: unresolved external symbol __imp__fopen
sslc_standard.lib(entropy.obj) : error LNK2001: unresolved external symbol __imp__fopen
sslc_standard.lib(def_pswd.obj) : error LNK2001: unresolved external symbol __imp__fopen
sslc_standard.lib(bss_file.obj) : error LNK2001: unresolved external symbol __imp___setmode
sslc_standard.lib(bss_file.obj) : error LNK2001: unresolved external symbol __imp__fileno
OLDNAMES.lib(fileno.obi) : error LNK2001: unresolved external symbol __imp__fileno
.......................
sslc_standard.lib(def_pswd.obj) : error LNK2001: unresolved external symbol __imp__getch
OLDNAMES.lib(getch.obi) : error LNK2001: unresolved external symbol __imp__getch
OLDNAMES.lib(fileno.obi) : error LNK2001: unresolved external symbol __imp___fileno
OLDNAMES.lib(stat.obi) : error LNK2001: unresolved external symbol __imp___stat
OLDNAMES.lib(getch.obi) : error LNK2001: unresolved external symbol __imp___getch
Debug/ssl_server.exe : fatal error LNK1120: 20 unresolved externals
Error executing link.exe.

ssl_server.exe - 32 error(s), 15 warning(s)
 

我知道一定是两头的配置有什么地方不一样,

于是我就连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

DUMB doesn't work in MSVC

 

现象都是先说一堆:"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可能会引发问题

 

C Run-Time Libraries

这一篇介绍了微软都给我们提供了那些crt.

 

/MD, /ML, /MT, /LD (Use Run-Time Library) 

这一主题共有好几个连接,讨论了不同编译器选项具体会使用那个crt,

下面列举两个,VS.60 ,VS.71

 

 

 

三、其他资源

 

VC6.0链接LIB的问题?

VC初学者经典错误LNK2001详解

VC++的链接错误LNK2001

讨论了其他可能引起LNK2001的原因,包括由编译错误引起的,还有由链接错误引起的。

 

error LNK2001: unresolved external symbol _main

error LNK2001: unresolved external symbol _main解决办法

error LNK2001: unresolved external symbol _main解决办法(zz)

讨论了一些原因的解决办法,包括本文中遇到的crt问题。

 

这三个链接是重复的,之所以列出三个,是我想大家独到这儿的时候,至少有一个会是有效的。

 

其他:

Use /MT[d] or /MD[d]?

有代码事例讨论了CRT,侧重Across DLL Boundary问题。

 

 

四、最后

 

附件是这篇上文提到的blog的pdf版本。

Choosing the Correct C/C++ Runtime Library

 

你可能感兴趣的:(C/C++,C++,C,C#,VC++,Qt)