vc链接静态库的时候要注意的问题

转载 2015年07月09日 14:16:48
vc工程与被链接的静态库(*.lib)文件之间要保持一致:

例如:  是共享模式使用MFC dll还是静态模式使用MFC dll?

是多线程还是单线程?

是调试模式还是release模式?

涉及的项目属性配置  /MDd   与 /MTd   /MD /MT


如果不一致,在链接阶段会报告错误,如:
LIBCMT.lib(invarg.obj) : error LNK2005: __initp_misc_invarg已经在 libcmtd.lib(invarg.obj) 中定义

或者函数无法解析


附(ZT)

1、VC编译选项
多线程 (/MT)
多线程调试 (/MTd)
多线程 DLL  (/MD)
多线程调试 DLL  (/MDd)

 

2、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      libcmtd.lib
MultiThread(dynamic link) MD           msvcrt.lib
Debug multiThread(dynamic link) MDdmsvcrtd.lib 

 

3. 各种 C运行时库的区别

 

(1)静态链接的单线程库
静态链接的单线程库只能用于单线程的应用程序, C 运行时库的目标代码最终被编译在应用程序的二进制文件中。通过 /ML编译选项可以设置 Visual C++ 使用静态链接的单线程库。

 

(2)静态链接的多线程库
静态链接的多线程库的目标代码也最终被编译在应用程序的二进制文件中,但是它可以在多线程程序中使用。通过 /MT编译选项可以设置 Visual C++ 使用静态链接的多线程库。

 

(3)动态链接的运行时库
动态链接的运行时库将所有的 C 库函数保存在一个单独的动态链接库 MSVCRTxx.DLL 中,MSVCRTxx.DLL处理了多线程问题。使用 /MD 编译选项可以设置 Visual C++ 使用动态链接的运行时库。
/MDd 、 /MLd 或 /MTd 选项使用 Debug runtime library( 调试版本的运行时刻函数库 ),与 /MD 、 /ML 或 /MT 分别对应。 Debug 版本的 Runtime Library包含了调试信息,并采用了一些保护机制以帮助发现错误,加强了对错误的检测,因此在运行性能方面比不上 Release版本。 

 

4、下面是msdn关于Visual C++编译器选项的说明:
这些选项选择单线程或多线程运行时例程,指示多线程模块是否为 DLL,并选择运行时库的发布版本或调试版本。
(1)/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。

 

(2)/MDd    定义 _DEBUG、_MT 和 _DLL,以便从标准 .h文件中选择运行时例程的调试多线程特定版本和 DLL 特定版本。它还使编译器将库名 MSVCRTD.lib 放入 .obj文件中。

 

(3)/ML    使编译器将库名 LIBC.lib 放入 .obj 文件中,以便链接器使用 LIBC.lib解析外部符号。这是编译器的默认操作。LIBC.lib 不提供多线程支持。

 

(4)/MLd    定义 _DEBUG 并使编译器将库名 LIBCD.lib 放入 .obj 文件中,以便链接器使用LIBCD.lib 解析外部符号。LIBCD.lib 不提供多线程支持。

 

(5)/MT    定义 _MT,以便从标准头 (.h)文件中选择运行时例程的多线程特定版本。此选项还使编译器将库名 LIBCMT.lib 放入 .obj 文件中,以便链接器使用LIBCMT.lib 解析外部符号。创建多线程程序需要 /MT    或 /MD(或它们的调试等效选项 /MTd 或 /MDd)。

 

(6)/MTd    定义_DEBUG 和 _MT。定义 _MT 会导致从标准 .h 文件中选择运行时例程的多线程特定版本。此选项还使编译器将库名LIBCMTD.lib 放入 .obj 文件中,以便链接器使用 LIBCMTD.lib 解析外部符号。创建多线程程序需要 /MTd 或/MDd(或它们的非调试等效选项 /MT 或 MD)。

 

(7)/LD    创建 DLL。将 /DLL 选项传递到链接器。链接器查找 DllMain函数,但并不需要该函数。如果没有编写 DllMain 函数,链接器将插入返回 TRUE 的 DllMain 函数。链接 DLL启动代码。如果命令行上未指定导出 (.exp) 文件,则创建导入库 (.lib);将导入库链接到调用您的 DLL 的应用程序。将/Fe 解释为命名 DLL 而不是 .exe 文件;默认程序名成为基名称.dll 而不是基名称.exe。如果还未显式指定 /M选项之一,则将默认运行时库支持更改为 /MT。

 

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


No.1 :错误 :Libcmtd.lib(wincrt0.obj) : error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用


解决方法:

项目 --> 属性 --> 配置属性 --> 链接器 --> 高级 --> 入口点 :    填写 wWinMainCRTStartup。


No.2 :错误:

1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) 已经在 LIBCMTD.lib(new.obj) 中定义
1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) 已经在 LIBCMTD.lib(dbgdel.obj) 中定义
1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U@YAPAXI@Z) 已经在 libcpmtd.lib(newaop.obj) 中定义
1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete[](void *)" (??_V@YAXPAX@Z) 已经在 LIBCMTD.lib(delete2.obj) 中定义

解决方法:

项目 --> 属性 --> 配置属性 --> 链接器 --> 输入 --> 附加依赖项 : 加入 

uafxcwd.lib 

Libcmtd.lib

项目 --> 属性 --> 配置属性 --> 链接器 --> 输入 --> 忽略特定默认库 :加入

uafxcwd.lib 

Libcmtd.lib


No.3:警告:

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\stdint.h(72): warning C4005: “INT8_MIN”: 宏重定义
1>          c:\program files (x86)\microsoft sdks\windows\v7.0a\include\intsafe.h(144) : 参见“INT8_MIN”的前一个定义
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\stdint.h(73): warning C4005: “INT16_MIN”: 宏重定义
1>          c:\program files (x86)\microsoft sdks\windows\v7.0a\include\intsafe.h(146) : 参见“INT16_MIN”的前一个定义
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\stdint.h(74): warning C4005: “INT32_MIN”: 宏重定义
1>          c:\program files (x86)\microsoft sdks\windows\v7.0a\include\intsafe.h(148) : 参见“INT32_MIN”的前一个定义
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\stdint.h(76): warning C4005: “INT8_MAX”: 宏重定义

解决方法:

在头文件中加入:


#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable : 4005)
#include <intsafe.h>
#include <stdint.h>
#pragma warning (pop)
#endif


No.4:警告:

取消 strcpy strcpy_s 这些警告。


解决方法:

项目 --> 属性 --> 配置属性 --> C/C++ --> 预处理器 --> 预处理器定义 :_CRT_SECURE_NO_WARNINGS 

再在头文件中加入

#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS 
#endif
举报

相关文章推荐

VC++中使用静态链接库和动态链接库小结(转帖)

最近在VC++使用GSL(GNU科学计算库)静态库和动态库时遇到了一些问题,做个小结,以备参考。       静态库包括.lib和.h文件,在工程中使用静态库分为3步:1在工程中加入静态库,有两种方法...
  • cworld
  • cworld
  • 2008-11-14 13:03
  • 2665

vc6静态库的生成和调用

vc6静态库的生成和调用

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

vc链接静态库的时候要注意的问题

 vc工程与被链接的静态库(*.lib)文件之间要保持一致: 例如:  是共享模式使用MFC dll还是静态模式使用MFC dll? 是多线程还是单线程? 是调试模...

VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结

Background MSDN中对于在不同的配置下Link的LIB作了说明: C Runtime Library: 开关 对应的库 版本 /...

VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结

VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结 2007-12-14 19:07 1019人阅读 评论(0) 收藏 举报 Background MS...

转:VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结

MSDN中对于在不同的配置下Link的LIB作了说明:C Runtime Library:开关对应的库版本/MDMSVCRT.LIB多线程DLL的Release版本/MDdMSVCRTD.LIB多线程...

VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结

Background MSDN中对于在不同的配置下Link的LIB作了说明: C Runtime Library: 开关 对应的库 版本 ...

VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结

Background MSDN中对于在不同的配置下Link的LIB作了说明: C Runtime Library: 开关 对应的库 版本 /...

转:VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结

MSDN中对于在不同的配置下Link的LIB作了说明:C Runtime Library:开关对应的库版本/MDMSVCRT.LIB多线程DLL的Release版本/MDdMSVCRTD.LIB多线程...

工程链接静态库的时候,通过删除class来解决重复的符号的错误

工程链接静态库的时候,通过删除class来解决重复符号(duplicate symbol)的错误         如果你在工程中使用静态库,并且指定了编译选项为-all_load(为了让Objecti...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)