VS2010运行时库参数设置说明

错误 1 error LNK2005: __cexit 已经在 MSVCRTD.lib(MSVCR100D.dll) 中定义 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(crt0dat.obj) LibH264
错误 2 error LNK2005: __amsg_exit 已经在 MSVCRTD.lib(MSVCR100D.dll) 中定义 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(crt0dat.obj) LibH264
错误 3 error LNK2005: __initterm_e 已经在 MSVCRTD.lib(MSVCR100D.dll) 中定义 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(crt0dat.obj) LibH264
错误 4 error LNK2005: ___CppXcptFilter 已经在 MSVCRTD.lib(MSVCR100D.dll) 中定义 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(winxfltr.obj) LibH264
错误 5 error LNK2005: __encoded_null 已经在 MSVCRTD.lib(MSVCR100D.dll) 中定义 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(tidtable.obj) LibH264
错误 6 error LNK2005: __malloc_dbg 已经在 MSVCRTD.lib(MSVCR100D.dll) 中定义 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(dbgheap.obj) LibH264
错误 7 error LNK2005: __free_dbg 已经在 MSVCRTD.lib(MSVCR100D.dll) 中定义 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(dbgheap.obj) LibH264
错误 8 error LNK2005: __CrtSetCheckCount 已经在 MSVCRTD.lib(MSVCR100D.dll) 中定义 d:\ProjectArchive\LibH264\LibH264\libcmtd.lib(dbgheap.obj) LibH264多线程


    这种错误常常会碰到吧?呵呵。。。。函数

   解决了这个问题的方法就是修改一下编译选项,将/MD选项改成/MT选项,最终的可执行文件就不会包含对那些VC运行时DLL的引用了,能够很方便的发布和部署。首先让咱们来看下这个云遮雾罩的编译开关到底是干什么的?MSDN中的描述以下:spa

/MD命令行

 使应用程序使用运行时库的多线程并特定于 DLL 的版本。定义 _MT 和 _DLL,并使编译器将库名 MSVCRT.lib 放入 .obj 文件中。线程

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

当 /MD 与 _STATIC_CPPLIB 预处理器定义 (/D_STATIC_CPPLIB) 一块儿使用时,您的应用程序将与静态多线程标准 C++ 库 (libcpmt.lib) 而非动态版本 (msvcprt.lib) 连接,但仍经过 msvcrt.lib 动态连接到主 CRT。code

请注意,不支持 _STATIC_CPPLIB 预处理器定义和 /clr 或 /clr:pure 编译器选项的组合。有关 /clr 选项的限制的更多信息,请参见 /clr 限制。orm

/MDd部署

 定义 _DEBUG、_MT 和 _DLL,并使应用程序使用运行时库的调试多线程并特定于 DLL 的版本。它还使编译器将库名 MSVCRTD.lib 放入 .obj 文件中。编译器

/MT

 使应用程序使用运行时库的多线程静态版本。定义 _MT 并使编译器将库名 LIBCMT.lib 放入 .obj 文件中,以便连接器使用 LIBCMT.lib 解析外部符号。

/MTd

 定义 _DEBUG 和 _MT。此选项还使编译器将库名 LIBCMTD.lib 放入 .obj 文件中,以便连接器使用 LIBCMTD.lib 解析外部符号。

/LD

 建立 DLL。

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

连接 DLL 启动代码。

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

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

除非显式指定 /MD,不然将暗指 /MT。

/LDd

 建立调试 DLL。定义 _MT 和 _DEBUG。

 

看到这里,我恍然大悟,原来这个开关就是控制这个C运行时库的引用方式的,真是踏破铁鞋无觅处得来全不费工夫。

固然到这里先别忙着去修改你的项目属性中关于这个开关的选项,由于当你的项目也是一个LIB时,若是使用了/MT或/MTd选项时,最终的静态LIB中就会出现LIBCMT.lib中的大量符号,致使在别的项目引用你的这个静态LIB时出现重复定义符号而没法连接的错误,怎么解决呢?其实继续看MSDN中的帮助就能够获得答案:

传递给连接器的给定调用的全部模块都必须使用相同的运行时库编译器选项(/MD、/MT、/LD)进行编译。

呵呵,原来如此,全部的模块保持一致就完了,可是静态的LIB貌似仍是没法引用,问题依旧怎么办呢?

那就是在引用了你本身的使用/MT或/MTd选项编译生成的静态LIB的项目中,不但指定对应的/MT或/MTd选项,并且须要忽略LIBCMT.lib库便可。

总结下来,《VC++语言参考手册》中其实早就描述过这个问题了,这本书有时间能够再看看。

相关文章
相关标签/搜索