选择正确的CC++ Runtime Library

    技术2025-01-16  18

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

    "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

    最新回复(0)