Visual C++ 编译器选项/MD、/ML、/MT、/LD

前段时间编译一个引用自己写的静态库的程序时老是出现链接时的多个重定义的错误,而自己的代码明明没有重定义这些东西,譬如:
LIBCMT.lib(_file.obj) : error LNK2005: ___initstdio already defined in libc.lib(_file.obj)
LIBCMT.lib(_file.obj) : error LNK2005: ___endstdio already defined in libc.lib(_file.obj)
LIBCMT.lib(_file.obj) : error LNK2005: __cflush already defined in libc.lib(_file.obj)
LIBCMT.lib(_file.obj) : error LNK2005: __iob already defined in libc.lib(_file.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __alloc_osfhnd already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __set_osfhnd already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __free_osfhnd already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __get_osfhandle already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(osfinfo.obj) : error LNK2005: __open_osfhandle already defined in libc.lib(osfinfo.obj)
LIBCMT.lib(tolower.obj) : error LNK2005: __tolower already defined in libc.lib(tolower.obj)
LIBCMT.lib(tolower.obj) : error LNK2005: _tolower already defined in libc.lib(tolower.obj)
等等。

所 以初步估计是编译器的问题,通过网上搜索和查看msdn,原来是Visual C++ 编译器选项的关于单线程或多线程运行时例程的问题:我的那个静态库编译时/ML单线程版本的,而引用它的程序是/MT多线程版本的,他们在编译分别讲 libc.lib和LIBCMT.lib连接到各自的代码中,估计libc.lib和LIBCMT.lib只是单线程与多线程的区别,基本代码相差无几, 所以会产生链接时重定义错误;然后把编译静态库的选项/ML改成/MT就没事了。

要注意的是:/MD也是多线程版本的;被应用的用户链接库 要和应用者有相同的编译选项,/MD与/MT一起有时候会有错误的,有时候就没有,我试过这种情况;而/MD和/ML似乎是没有问题的;/MT和/ML是 肯定会有问题的。有没有其他情况就不清楚了,有兴趣的可以测试一下,^_^

如果是代码是用于多线程的,最好编译成多线程版本的,否则可能会出现一些意想不到的问题。

编译器选项设置(vc6):工程 -> 设置 -> C/C++ -> 工程选项   里可以修改

附:

下面是msdn关于Visual C++ 编译器选项的说明:

这些选项选择单线程或多线程运行时例程,指示多线程模块是否为 DLL,并选择运行时库的发布版本或调试版本。

选项 说明
/MD 定义 _MT 和 _DLL 以便同时从标准 .h 文件中选择运行时例程的多线程特定版本和 DLL 特定版本。此选项还使编译器将库名 MSVCRT.lib 放入 .obj 文件中。

用此选项编译的应用程序静态链接到 MSVCRT.lib。该库提供允许链接器解析外部引用的代码层。实际工作代码包含在 MSVCR71.DLL 中,该库必须在运行时对于与 MSVCRT.lib 链接的应用程序可用。

当 在定义了 _STATIC_CPPLIB (/D_STATIC_CPPLIB) 的情况下使用 /MD 时,它将导致应用程序通过静态多线程标准 C++ 库 (libcpmt.lib) 而非动态版本 (msvcprt.lib) 进行链接,同时仍通过 msvcrt.lib 动态链接到主 CRT。

/MDd 定义 _DEBUG_MT 和 _DLL,以便从标准 .h 文件中选择运行时例程的调试多线程特定版本和 DLL 特定版本。它还使编译器将库名 MSVCRTD.lib 放入 .obj 文件中。
/ML 使编译器将库名 LIBC.lib 放入 .obj 文件中,以便链接器使用 LIBC.lib 解析外部符号。这是编译器的默认操作。LIBC.lib 不提供多线程支持。
/MLd 定义 _DEBUG 并使编译器将库名 LIBCD.lib 放入 .obj 文件中,以便链接器使用 LIBCD.lib 解析外部符号。LIBCD.lib 不提供多线程支持。
/MT 定义 _MT, 以便从标准头 (.h) 文件中选择运行时例程的多线程特定版本。此选项还使编译器将库名 LIBCMT.lib 放入 .obj 文件中,以便链接器使用 LIBCMT.lib 解析外部符号。创建多线程程序需要 /MT 或 /MD(或它们的调试等效选项 /MTd 或 /MDd)。
/MTd 定义 _DEBUG 和 _MT。定义 _MT 会导致从标准 .h 文件中选择运行时例程的多线程特定版本。此选项还使编译器将库名 LIBCMTD.lib 放入 .obj 文件中,以便链接器使用 LIBCMTD.lib 解析外部符号。创建多线程程序需要 /MTd 或 /MDd(或它们的非调试等效选项 /MT 或 MD)。
/LD 创建 DLL。

将 /DLL 选项传递到链接器。链接器查找 DllMain 函数,但并不需要该函数。如果没有编写 DllMain 函数,链接器将插入返回 TRUE 的 DllMain 函数。

链接 DLL 启动代码。

如果命令行上未指定导出 (.exp) 文件,则创建导入库 (.lib);将导入库链接到调用您的 DLL 的应用程序。

将 /Fe 解释为命名 DLL 而不是 .exe 文件;默认程序名成为基名称.dll 而不是基名称.exe。

如果还未显式指定 /M 选项之一,则将默认运行时库支持更改为 /MT。

/LDd 创建调试 DLL。定义 _DEBUG

警告    不要混合使用运行时库的静态版本和动态版本。在一个进程中有多个运行时库副本会导致问题,因为副本中的静态数据不与其他副本共享。链接器禁止在 .exe 文件内部既使用静态版本又使用动态版本链接,但您仍可以使用运行时库的两个(或更多)副本。例如,当与用动态 (DLL) 版本的运行时库链接的 .exe 文件一起使用时,用静态(非 DLL)版本的运行时库链接的动态链接库可能导致问题。(还应该避免在一个进程中混合使用这些库的调试版本和非调试版本)。

有关使用运行时库的调试版本的更多信息,请参见运行时库参考。

知识库文章 Q140584 也讨论如何选择适当的 C 运行时库。

有关 DLL 的进一步讨论,请参见 DLL

在 Visual Studio 开发环境中设置此编译器选项

  1. 打开此项目的“属性页”对话框。有关详细信息,请参见设置 Visual C++ 项目属性
  2. 单击“C/C++”文件夹。
  3. 单击“代码生成”属性页。
  4. 修改“运行时库”属性。

以编程方式设置此编译器选项

请参见 RuntimeLibrary 属性。

时间: 2024-11-06 14:14:47

Visual C++ 编译器选项/MD、/ML、/MT、/LD的相关文章

(转)VC运行库MD /MDd /MT /MTd /ML /MLd

VC编译选项 - 多线程(/MT) - 多线程调试 (/MTd) - 多线程DLL (/MD) - 多线程调试DLL (/MDd) C 运行时库 库文件 - Single thread(static link) ML libc.lib - Debug single thread(static link) MLd libcd.lib - MultiThread(static link) MT libcmt.lib - Debug multiThread(static link) MTd libcm

md /mdd /ml /mt/mtd

http://www.cnblogs.com/eddyshn/archive/2009/11/23/1608823.html VC编译选项 多线程(/MT)多线程调试(/MTd)多线程 DLL (/MD)多线程调试 DLL (/MDd)C 运行时库                        库文件Single thread(static link) ML            libc.libDebug single thread(static link) MLd        libcd.

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

msdn Indicates whether a multithreaded module is a DLL and specifies retail or debug versions of the run-time library. Copy /MD[d] /MT[d] /LD[d] Remarks Option Description /MD Causes the application to use the multithread-specific and DLL-specific ve

md/mdd/mt/mtd

  名称 说明 mt   多线程 定义了_MT 并使编译器将库名 LIBCMT.lib 放入 .obj 文件中  mtd    多线程调试 定义_DEBUG 和 _MT.此选项还使编译器将库名 LIBCMTD.lib 放入 .obj 文件中 md   多线程DLL 定义了_MT 和 _DLL,并使编译器将库名 MSVCRT.lib 放入 .obj文件中. mdd   多线程DLL调试 定义_DEBUG._MT 和 _DLL,将MSVCRTD.lib 放入 .obj 文件中. 注意: 使用相同的编

Visual studio编译器窗口重置

针对vs2003: 第一种方法 在"工具"->"选项"对话框里面: 在"选项"下面的"常规"有个"重置窗口布局"按钮. 第二种方法 把 Documents   and   Settings\用户名\Application   Data\Microsoft\VisualStudio\7.1 下的所有文件都删除,然后重新开vs2003   OK: Visual studio编译器窗口重置

编译器选项

将msdn上vs2013的编译器选项记载一下,我不创造文章,我只是大自然的搬运工: 1./STACK(堆栈分配) /STACK:reserve[,commit] /STACK 选项设置堆栈的大小(以字节为单位).此选项仅在生成 .exe 文件时使用. 该选项指定虚拟内存中的总的堆栈分配.默认堆栈大小为 1 MB.链接器将指定值向上舍入为最接近的 4 个字节. commit 取决于操作系统所作的解释.在 Windows NT 和 Windows 2000 中,它指定一次分配的物理内存量.提交的虚拟

makefile中一些编译器选项

makefile中一些编译器选项 CFLAGS CXXFLAGS CFLAGS 表示用于 C 编译器的选项 CXXFLAGS 表示用于 C++ 编译器的选项 这两个变量实际上涵盖了__编译__和__汇编__两个步骤 指定头文件(.h文件)的路径 CFLAGS=-I/usr/include -I/path/include (安装一个包时会在安装路径下建立一个include目录,当安装过程中出现问题时,试着把以前安装的包的include目录加入到该变量中来) LDFLAGS gcc等编译器会用到的一

Visual C++ 编译器自动假定带 .C 扩展名的文件是 C 文件而不是 C++ 文件,并且拒绝 C++ 语法和关键字(c语言只能在大括号最前面申明变量)

今天在编译OpenGL红宝书附带源码中的light.c文件时遇到一个诡异的问题: 如图light .c,在不做任何修改的情况编译OK.然而只要在某些地方写了可执行代码,则会无法通过编译器编译! (这几行代码如果写在main函数里的第一句则OK) 我用的VS08.我把该文件发给其他朋友(用的VS10),同样也是这样的问题. 然而,我把文件名改成light.cpp后,问题解决了. 现在的问题是,代码文件按的后缀背后,会如何影响编辑器的编译呢? 可以做一个简单的测试: [cpp] view plain

QtCreator (Visual C++ 编译器)编译时提示 warning C4819 的解决办法

用 QtCreator + Visual C++ 编译器 编译程序时经常会出现类似的警告. warning C4819: 该文件包含不能在当前代码页(936)中表示的字符.请将该文件保存为 Unicode 格式以防止数据丢失 这个警告我们可以忽略,但是编译大一点的项目时经常会提示几十个这样的警告,也挺烦人的. 其实解决办法也很简单,将我们的代码保存为 utf-8 带 BOM 格式的文件就可以了.QtCreator 保存文件默认是 utf-8 格式的,但是不带 BOM. 我们可以修改一下设置,让它