如何用正确的 C 运行时 (CRT) 库的链接

文章翻译 文章翻译
文章编号: 140584 - 查看本文应用于的产品
展开全部 | 关闭全部

本文内容

概要

有六种类型的可重用的库:
  • 静态单线程库 (调试/释放)
  • 静态多线程的库 (调试/释放)
  • 动态链接库 (DLL)(Debug/Release)
注意每个库都有一个调试版本和发布版本。

DLL 是安全的多线程并不将 CRT 库的一个单线程版本提供的 dll。如果可重用的库的任何用户正在使用多个线程,则需要为多线程安全的库类型库。

注意调试库和编译器开关 /MLd、 /MTd 和 /MDd 才可在 Visual c + + 版本 4.0 及更高版本。

下表显示了用于构建的每个六种类型的可重用的库 (DLL 的所有类型都是多线程安全) 的编译器开关。使用可重用的库的任何项目应该使用相同的编译器开关。在使用 /ML(default)、 / MT MLd,、 MTd,/MD 或 /MDd 编译器切换参数时编译器将 (在库列列出) 默认库名放在对象文件中。
Reusable Library            Switch    Library    Macro(s) Defined
----------------------------------------------------------------
Single Threaded             /ML       LIBC       (none)
Static MultiThread          /MT       LIBCMT     _MT
Dynamic Link (DLL)          /MD       MSVCRT     _MT and _DLL
Debug Single Threaded       /MLd      LIBCD      _DEBUG
Debug Static MultiThread    /MTd      LIBCMTD    _DEBUG and _MT
Debug Dynamic Link (DLL)    /MDd      MSVCRTD    _DEBUG, _MT, and _DLL
				
您可以查看的对象模块,以确定它生成使用此命令时,所使用的开关:
   dumpbin /all <object>.obj
				
RAW 数据 # 1 一节中查找。在最右侧的列中将列出默认库。

更多信息

可重用的库和所有其用户应使用相同的 CRT 库类型,因此相同的编译器开关。宏定义 (或未定义) 为每个编译器开关可重用库的头文件中用来强制实施正确的编译器开关。在这篇文章中的代码示例演示了如何使用这些宏。

如果需要能够选择静态库或 DLL CRT 的用户,则应提供静态和 DLL 的可重用的库类型。

如果您选择混合使用 CRT 库,请记住,具有,具有独立且不同状态的两个不同副本因此您必须是 CRT 的您试图执行跨 CRT 边界时要小心。有两个 CRTs 疑难到的许多方法。下面是几个:
  • 有两个单独的堆。您不能分配 (新的 malloc 使用显式或这样上--或隐式使用 strdup、 strstreambuf::str,或等等),然后将指针传递跨指向将释放 CRT 边界。
  • 您不能跨 CRT 边界传递 FILE * 或文件的句柄和需要在"stdio 低级 IO"工作。
  • 您不能在其中一个设置区域设置和需要对方的区域设置。
从 Visual c + + 4.0 开始链接器将发出警告 (LNK4098) 如果生成模块试图合并的 CRT 库的多个副本。有关详细的信息搜索 LNK4098 帮助文件。

示例代码

下面的代码可重用库的头文件中用来确保在使用一致的正确的编译器开关:
// MyReusableStaticSingleThreadReleaseLibrary.h
#if defined(_MT) || defined(_DEBUG)
    #error The /ML compiler switch is required.
#endif

// MyReusableStaticMultithreadReleaseLibrary.h
#if !defined(_MT) || defined(_DLL) || defined(_DEBUG)
    #error The /MT compiler switch is required.
#endif

// MyReusableDynamicLinkReleaseLibrary.h
#if !defined(_MT) || !defined(_DLL) || defined(_DEBUG)
    #error The /MD compiler switch is required.
#endif

// MyReusableStaticSingleThreadDebugLibrary.h
#if defined(_MT) || !defined(_DEBUG)
    #error The /MLd compiler switch is required.
#endif

// MyReusableStaticMultithreadDebugLibrary.h
#if !defined(_MT) || defined(_DLL) || !defined(_DEBUG)
    #error The /MTd compiler switch is required.
#endif

// MyReusableDynamicLinkDebugLibrary.h
#if !defined(_MT) || !defined(_DLL) || !defined(_DEBUG)
    #error The /MDd compiler switch is required.
#endif
				

属性

文章编号: 140584 - 最后修改: 2004年7月1日 - 修订: 3.1
这篇文章中的信息适用于:
  • Microsoft Visual C++ 2.0 Professional Edition
  • Microsoft Visual C++ 2.1
  • Microsoft Visual C++ 2.2
  • Microsoft Visual C++ 4.0 标准版
  • Microsoft Visual C++ 4.0 标准版
  • Microsoft Visual C++ 4.1 Subscription
  • Microsoft Visual C++ 4.2 专业版
  • Microsoft Visual C++ 4.2 专业版
  • Microsoft Visual C++ 5.0 标准版
  • Microsoft Visual C++ 6.0 Service Pack 5
  • Microsoft Visual C++ .NET 2002 标准版
  • Microsoft Visual C++ .NET 2003 Standard Edition
关键字:?
kbmt kbcrt kbhowto KB140584 KbMtzh
机器翻译
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。
点击这里察看该文章的英文版: 140584
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com