VS默认库相关学习
1. 在编译pjsua工程时,vs2012产生了错误:默认库“library”与其他库的使用冲突;使用 /NODEFAULTLIB:library
1.1原因
重要事项 运行时库现在包含防止混合不同类型的指令。如果试图在同一个程序中使用不同类型的运行时库
或使用调试和非调试版本的运行时库,则将收到此警告。例如,如果编译一个文件以使用一种运行时库,
而编译另一个文件以使用另一种运行时库(例如单线程运行时库对多线程运行时库),并试图链接它们,
则将得到此警告。应将所有源文件编译为使用同一个运行时库。有关更多信息,请参阅使用运行时库(/MD
、/ML、/MT、/LD)编译器选项。可以使用链接器的 /VERBOSE:LIB 开关来确定链接器搜索的库。如果收到
LNK4098,并想创建使用如单线程、非调试运行时库的可执行文件,请使用 /VERBOSE:LIB 选项确定链接
器搜索的库。链接器作为搜索的库输出的应是 LIBC.lib,而非 LIBCMT.lib、MSVCRT.lib、LIBCD.lib、
LIBCMTD.lib 和 MSVCRTD.lib。对每个要忽略的库可以使用 /NODEFAULTLIB,以通知链接器忽略错误的运
行时库。
下表显示根据要使用的运行时库应忽略的库。
若要使用此运行时库 请忽略这些库
版 本 | 类 型 | 使用的library | 被忽略的library |
R Release | 单线程 | libc.lib | libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib |
多线程 | libcmt.lib | libc.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib | |
使用DLL的多线程 | msvcrt.lib | libc.lib, libcmt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib | |
D Debug | 单线程 | libcd.lib | libc.lib, libcmt.lib, msvcrt.lib, libcmtd.lib, msvcrtd.lib |
多线程 | libcmtd.lib | libc.lib, libcmt.lib, msvcrt.lib, libcmtd.lib, msvcrtd.lib | |
使用DLL的多线程 | msvcrtd.lib | libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib |
1.2 解决办法
如果收到"默认库“LIBCMTD”与其他库的使用冲突;请使用 /NODEFAULTLIB:library"此警告,并希望创建使用非调试、单/多线程版本的运行时库的可执行文件,解决办法:
1)重新配静态库:“配置属性-->链接器-->输入-->忽略特定库”中把libcmt.lib添加进去(单/多线程版本)或者在“配置属性-->链接器-->命令运”的“附加选项”添加上:/NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib(仅限于单线程版本)
2)VC编译选项:工程项-->属性-->C/C++-->代码生成-->运行库(下拉选择):
多线程(/MT)
多线程调试(/MTd)
多线程 DLL (/MD)
多线程调试 DLL (/MDd)
各运行时库的区别:http://aaroncao.blog.51cto.com/8009152/1586607
3)libcmtd 这个库有时候不能忽略,忽略后会有不能解析的外部符号错误
其实有个方便的方法 链接时加入参数 /FORCE:MULTIPLE
1.2 总结
这个报错本身是说明你运行库的使用有误,比如用了Debug的运行时库去生成Release的目标文件。如果你使用正确这个错误会自动消失。
2.安装、使用libcurl库
2.1 libcurl相关资料:
libcurl是一个支持跨平台的HTTP/HTPPSFTP/RTSP/TELNET函数库
(开源组织http://curl.haxx.se/libcurl/)
自带VC工程, 使用时需要链接这些库: libcurld.lib ws2_32.lib winmm.lib wldap32.lib
libcurld.lib: 网络通信协议相关库
ws2_32.lib: 网络通信相关库
winmm.lib: 媒体播放相关库
wldap32.lib:
Linux用configure->make编译(缺省同时生成静态库和动态库),
./configure --enable-ipv6 --disable-ldap 可以去除对openldap的依赖
用下面两个命令可以获取链接libcurl库的编译参数:
$ ./curl-config --static-libs
/usr/local/lib/libcurl.a -lssl -lcrypto -lldap -lrt -lssl -lcrypto -ldl -lz -lz
$ ./curl-config --libs
-L/usr/local/lib -lcurl
2.2 libcurl库的安装
访问网页的时候我选择了gzip压缩,因此添加了zlib包,如果不需要zlib跳过步骤2
2.2.1 下载源代码:
下载libcurl:
打开:http://curl.haxx.se/download.html
在Source Archives下面有类似:curl 7.20.0 , Released on the 9th of February 2010 .
这下面的4个链接随便下载一个解压就行
下载zlib:
打开:http://www.zlib.net/
搜索:The current release is publicly available here:
这下面的链接都一样,只不过压缩方式或者网址不一样,随便下载个解压就行
2.2.2 静态编译zlib:
注:因为我的程序就一个exe文件,不想带一堆dll发布,因此选择了静态编译libcurl,zlib也静态编译了
zlib源代码解压后默认的目录名为:zlib-1.2.3,进入目录projects/visualc6,打开zlib.dsw(用高版本vc系统会提示转成相应的版本)
在vc菜单里选择 "生成->批生成",再lib debug和lib release后面打钩,点“生成”,生成的zlib.lib和zlibd.lib分别在Win32_LIB_Release和Win32_LIB_Debug目录下
2.2.3 静态编译libcurl:
注:将解压后的libcurl和zlib目录放到一起,比如将curl-7.20.0和zlib-1.2.3都放到d:/source下,编译的时候 libcurl默认zlib和自己在相同的目录下
编译参数的确定:
libcurl加压后的目录为:curl-7.20.0,进入目录lib,找到Makefile.vc9文件,这个里面有各种编译参数,有时间可以仔细的看看
这里给个简单的列子:先搜索 # release ,这下面都是不同的编译命令选项(就是后面用到的set CFG=xxx),我想静态编译libcurl库而且zlib也是静态编译,因此选择release-zlib
编译release版本: (我用的vc2008就是vc9了)
先把zlib-1.2.3/projects/visualc6/Win32_LIB_Release目录下的zlib.lib复制到zlib-1.2.3目录下
set CFG=release-zlib
nmake -f Makefile.vc9
编译完成后去release-zlib目录下找到libcurl.lib,这个就是生成的库了
编译debug版本:
方法同上,注意先将zlib-1.2.3/projects/visualc6/Win32_LIB_Debug目录下的zlibd.lib改成zlib.lib放到zlib-1.2.3目录下
编译:
set CFG=debug-zlib
nmake -f Makefile.vc9
下面这2个就是生成的libcurl库了
curl-7.20.0/lib/release-zlib/libcurl.lib
curl-7.20.0/lib/debug-zlib/libcurld.lib
2.2.4 在VS2010中VC++目录中加入从zip中解压的include目录,和lib目录
2.3 安装过程异常的处理
2.3.1 下载libcurl的源码,打开lib文件夹下项目,编译为静态链接库。在编译的时候出现问题如下:
注:以前在vc2005下用mfc工程并且libcurl用的dll方式没问题,这次vc2008用的sdk并且libcurl用的静态编译,也不知道什么问题引起的
HttpWebRequest.obj : error LNK2001: 无法解析的外部符号 __imp__curl_slist_free_all
1>HttpWebRequest.obj : error LNK2001: 无法解析的外部符号 __imp__curl_easy_cleanup
1>HttpWebRequest.obj : error LNK2001: 无法解析的外部符号 __imp__curl_easy_getinfo
1>HttpWebRequest.obj : error LNK2001: 无法解析的外部符号 __imp__curl_easy_setopt
1>HttpWebRequest.obj : error LNK2001: 无法解析的外部符号 __imp__curl_slist_append
1>HttpWebRequest.obj : error LNK2001: 无法解析的外部符号 __imp__curl_easy_init
1>HttpWebRequest.obj : error LNK2001: 无法解析的外部符号 __imp__curl_global_init
1>HttpWebRequest.obj : error LNK2001: 无法解析的外部符号 __imp__curl_easy_perform
2.3.2 解决问题的具体步骤:
1)给工程添加依赖的库:项目->属性->链接器->输入->附加依赖项,把libcurl.lib ws2_32.lib winmm.lib wldap32.lib添加进去。
注意,debug配置用libcurld.lib
2)加入预编译选项:项目->属性->c/c++ ->预处理器->预处理器,把 ;BUILDING_LIBCURL;HTTP_ONLY复制进去(注意不要丢了";")。
转载链接:http://www.cnblogs.com/zdxster/archive/2011/01/27/1945877.htm
l
转载于:https://blog.51cto.com/aaroncao/1586552